package com.rede.didiok.rank.service.impl;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import cn.hutool.core.util.RandomUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rede.didiok.common.constant.conf.MessageConf;
import com.rede.didiok.common.constant.conf.RedisConf;
import com.rede.didiok.common.constant.conf.SQLConf;
import com.rede.didiok.common.constant.conf.SysConf;
import com.rede.didiok.common.constant.conf.base.BaseSQLConf;
import com.rede.didiok.common.constant.conf.base.BaseSysConf;
import com.rede.didiok.common.constant.global.Constants;
import com.rede.didiok.common.constant.global.DefaultConstants;
import com.rede.didiok.common.convert.AggEsDocConvert;
import com.rede.didiok.common.domainEvent.EventAction;
import com.rede.didiok.common.dto.BusinessIdListDto;
import com.rede.didiok.common.dto.BusinessObjectListDto;
import com.rede.didiok.common.dto.ContinuousDayDto;
import com.rede.didiok.common.dto.admin.AdminDto;
import com.rede.didiok.common.dto.es.RankMemberEsModel;
import com.rede.didiok.common.dto.rank.*;
import com.rede.didiok.common.dto.user.GeneralEditDto;
import com.rede.didiok.common.dto.user.UserDto;
import com.rede.didiok.common.enums.*;
import com.rede.didiok.common.exception.exceptionType.FeignException;
import com.rede.didiok.common.exception.exceptionType.QueryException;
import com.rede.didiok.common.exception.exceptionType.UpdateException;
import com.rede.didiok.common.feign.*;
import com.rede.didiok.common.holder.RequestHolder;
import com.rede.didiok.common.schema.AggEsDoc;
import com.rede.didiok.common.utils.*;
import com.rede.didiok.common.utils.business.*;
import com.rede.didiok.rank.dao.*;
import com.rede.didiok.rank.entity.*;
import com.rede.didiok.rank.event.rankMemberEvent.RankMemberAddEvent;
import com.rede.didiok.rank.event.rankMemberEvent.RankMemberAuditEvent;
import com.rede.didiok.rank.event.rankMemberEvent.RankMemberDeleteEvent;
import com.rede.didiok.rank.service.*;
import com.rede.didiok.rank.vo.Attrs;
import com.rede.didiok.rank.vo.RankMemberAttrGroupVo;
import com.rede.didiok.rank.vo.RankMemberDetailVo;
import com.rede.didiok.rank.vo.RankMemberSaveVo;

@Slf4j
@Service("rankMemberService")
public class RankMemberServiceImpl extends ServiceImpl<RankMemberDao, RankMemberEntity> implements RankMemberService {

    @Resource
    private AttrValueService attrValueService;
    @Resource
    private MemberVisitService memberVisitService;
    @Resource
    private AttrService attrService;
    @Resource
    private RankService rankService;
    @Resource
    private RankCategoryService rankCategoryService;
    @Resource
    private SearchFeignClient searchFeignClient;
    @Resource
    private PayFeignClient payFeignClient;
    @Resource
    private RankPraiseRecordService rankPraiseRecordService;
    @Resource
    private MemberContentService memberContentService;
    @Resource
    private VoteCountService voteCountService;
    @Resource
    private AttrGroupService attrGroupService;
    @Resource
    private MemberGradeDao memberGradeDao;
    @Resource
    private VoteCountDao voteCountDao;
    @Resource
    private RankMemberDao rankMemberDao;
    @Resource
    private RankDao rankDao;
    @Resource
    private MemberTagDao memberTagDao;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private AttrInfoService attrInfoService;

    /**
     * 领域事件工具类
     */
    @Resource
    private DomainEventUtil domainEventUtil;


    @Resource
    ApplicationContext context;
    @Resource
    private WebUtil webUtil;
    @Resource
    private MemberTagService memberTagService;
    @Resource
    private MemberGradeService memberGradeService;
    @Resource
    private MemberContentDao memberContentDao;
    @Resource
    private RankCategoryDao rankCategoryDao;
    @Resource
    private MemberCommentDao memberCommentDao;
    @Resource
    private FileFeignClient fileFeignClient;
    @Resource
    private UserFeignClient userFeignClient;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private AdminFeignClient adminFeignClient;
    @Resource
    private RabbitMqUtil rabbitMqUtil;
    @Resource
    private FileFeignUtil fileFeignUtil;
    @Resource
    private UserUtil userUtil;

    /***************************** didiok-admin:start **************************/
    // region  didiok-admin

    /**
     * 获取状态 status=1 的榜单成员的总数量
     */
    @Override
    public Integer getRankMemberCount() {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(BaseSQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(BaseSQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        return rankMemberDao.selectCount(queryWrapper);
    }

    /**
     * 获取每个rank榜单下的榜单成员数目
     */
    @Override
    public List<Map<String, Object>> getRankMemberCountByRank() {
        // 从Redis中获取标签下包含的博客数量
        String jsonArrayList = redisUtil.get(RedisConf.DASHBOARD + Constants.SYMBOL_COLON + RedisConf.RANK_MEMBER_COUNT_BY_RANK);
        if (StringUtils.isNotEmpty(jsonArrayList)) {
            ArrayList jsonList = JsonUtils.jsonArrayToArrayList(jsonArrayList);
            return jsonList;
        }

        List<Map<String, Object>> MemberCountByTagMap = rankMemberDao.getMemberCountByRank();
        Map<String, Integer> rankMap = new HashMap<>();
        for (Map<String, Object> item : MemberCountByTagMap) {
            String rankUid = String.valueOf(item.get(SQLConf.RANK_UID));
            // java.lang.Number是Integer,Long的父类
            Number num = (Number) item.get(SysConf.COUNT);
            Integer count = num.intValue();
            //如果只有一个UID的情况
            if (rankUid.length() == 32) {
                //如果没有这个内容的话，就设置
                if (rankMap.get(rankUid) == null) {
                    rankMap.put(rankUid, count);
                } else {
                    Integer tempCount = rankMap.get(rankUid) + count;
                    rankMap.put(rankUid, tempCount);
                }
            } else {
                //如果长度大于32，说明含有多个UID
                if (StringUtils.isNotEmpty(rankUid)) {
                    List<String> strList = StringUtils.changeStringToString(rankUid, ",");
                    for (String strItem : strList) {
                        if (rankMap.get(strItem) == null) {
                            rankMap.put(strItem, count);
                        } else {
                            Integer tempCount = rankMap.get(strItem) + count;
                            rankMap.put(strItem, tempCount);
                        }
                    }
                }
            }
        }

        //把查询到的Rank放到Map中
        Set<String> rankUids = rankMap.keySet();
        Collection<RankEntity> rankCollection = new ArrayList<>();
        if (rankUids.size() > 0) {
            rankCollection = rankDao.selectBatchIds(rankUids);
        }

        Map<String, String> rankEntityMap = rankCollection.stream().collect(Collectors.toMap(RankEntity::getUid, RankEntity::getRankName, (v1, v2) -> v2));

        List<Map<String, Object>> resultList = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : rankMap.entrySet()) {
            String rankUid = entry.getKey();
            if (rankEntityMap.get(rankUid) != null) {
                String rankName = rankEntityMap.get(rankUid);
                Integer count = entry.getValue();
                Map<String, Object> itemResultMap = new HashMap<>();
                itemResultMap.put(SysConf.RANK_UID, rankUid);
                itemResultMap.put(SysConf.NAME, rankName);
                itemResultMap.put(SysConf.VALUE, count);
                resultList.add(itemResultMap);
            }
        }
        // 将 每个标签下文章数目 存入到Redis【过期时间2小时】
        if (resultList.size() > 0) {
            redisUtil.setEx(RedisConf.DASHBOARD + Constants.SYMBOL_COLON + RedisConf.RANK_MEMBER_COUNT_BY_RANK, JsonUtils.objectToJson(resultList), 2, TimeUnit.HOURS);
        }
        return resultList;
    }

    /**
     * 获取一年内发布的榜单成员数
     *
     * @return
     */
    @Override
    public Map<String, Object> getRankMemberContributeCount() {
        // 从Redis中获取博客分类下包含的博客数量
        String jsonMap = redisUtil.get(RedisConf.DASHBOARD + Constants.SYMBOL_COLON + RedisConf.RANK_MEMBER_CONTRIBUTE_COUNT);
        if (StringUtils.isNotEmpty(jsonMap)) {
            Map<String, Object> resultMap = JsonUtils.jsonToMap(jsonMap);
            return resultMap;
        }

        // 获取今天结束时间
        String endTime = DateUtils.getNowTime();
        // 获取365天前的日期
        Date temp = DateUtils.getDate(endTime, -365);
        String startTime = DateUtils.dateTimeToStr(temp);
        List<Map<String, Object>> rankMemberContributeMap = rankMemberDao.getRankMemberContributeCount(startTime, endTime);
        List<String> dateList = DateUtils.getDayBetweenDates(startTime, endTime);
        Map<String, Object> dateMap = new HashMap<>();
        for (Map<String, Object> itemMap : rankMemberContributeMap) {
            dateMap.put(itemMap.get("DATE").toString(), itemMap.get("COUNT"));
        }

        List<List<Object>> resultList = new ArrayList<>();
        for (String item : dateList) {
            Integer count = 0;
            if (dateMap.get(item) != null) {
                count = Integer.valueOf(dateMap.get(item).toString());
            }
            List<Object> objectList = new ArrayList<>();
            objectList.add(item);
            objectList.add(count);
            resultList.add(objectList);
        }

        Map<String, Object> resultMap = new HashMap<>(Constants.NUM_TWO);
        List<String> contributeDateList = new ArrayList<>();
        contributeDateList.add(startTime);
        contributeDateList.add(endTime);
        resultMap.put(SysConf.CONTRIBUTE_DATE, contributeDateList);
        resultMap.put(SysConf.RANK_MEMBER_CONTRIBUTE_COUNT, resultList);
        // 将 全年博客贡献度 存入到Redis【过期时间2小时】
        redisUtil.setEx(RedisConf.DASHBOARD + Constants.SYMBOL_COLON + RedisConf.RANK_MEMBER_CONTRIBUTE_COUNT, JsonUtils.objectToJson(resultMap), 2, TimeUnit.HOURS);
        return resultMap;
    }

    @Override
    public IPage<RankMemberEntity> getPageListWithGradeAndRankAndTag(RankMemberDto rankMemberDto) {

        //分页
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(rankMemberDto.getCurrentPage());
        page.setSize(rankMemberDto.getPageSize());

        if (ActivityOrderByEnum.FORWARD.getCode().equals(rankMemberDto.getActivityOrderBy())) {
            // 按照活动开始时间降序
            rankMemberDto.setAttrOrderBy(SQLConf.START_TIME + " desc");
        } else if (ActivityOrderByEnum.LATEST_RELEASE.getCode().equals(rankMemberDto.getActivityOrderBy())) {
            // 按照创建时间降序
            rankMemberDto.setOrderBy(SQLConf.CREATE_TIME + " desc");
        } else if (ActivityOrderByEnum.HISTORY.getCode().equals(rankMemberDto.getActivityOrderBy())) {
            // 按照活动开始时间降序
            rankMemberDto.setAttrOrderBy(SQLConf.START_TIME + " desc");
        } else {
            // 按照活动开始时间升序
            rankMemberDto.setAttrOrderBy(SQLConf.START_TIME + " asc");
        }

        Page<RankMemberEntity> pageList = rankMemberDao.queryPageWithAttrInfo(page, rankMemberDto);
        List<RankMemberEntity> list = pageList.getRecords();

        if (list.size() == 0) {
            return pageList;
        }
        List<String> rankUids = new ArrayList<>();
        List<String> tagUids = new ArrayList<>();
        List<String> gradeUids = new ArrayList<>();
        Date nowDate = new Date();
        list.forEach(item -> {

            // 是否活动结束
            if(null != item.getEndTime()){
                item.setIsEnd(nowDate.after(item.getEndTime()) ? 1 : 0);
            }

            // 是否报名截止
            if(null != item.getApplyEndTime()) {
                item.setIsApplyEnd(nowDate.after(item.getApplyEndTime()) ? 1 : 0);
            }
            if (StringUtils.isNotEmpty(item.getRankUid())) {
                rankUids.add(item.getRankUid());
            }
            if (StringUtils.isNotEmpty(item.getGradeUid())) {
                gradeUids.add(item.getGradeUid());
            }
            if (StringUtils.isNotEmpty(item.getTagUid())) {
                List<String> tagUidsTemp = StringUtils.changeStringToString(item.getTagUid(), SysConf.FILE_SEGMENTATION);
                for (String itemTagUid : tagUidsTemp) {
                    tagUids.add(itemTagUid);
                }
            }
        });
        Collection<RankEntity> rankList = new ArrayList<>();
        Collection<MemberGradeEntity> gradeList = new ArrayList<>();
        Collection<MemberTagEntity> tagList = new ArrayList<>();

        if (rankUids.size() > 0) {
            rankList = rankService.listByIds(rankUids);
        }
        if (gradeUids.size() > 0) {
            gradeList = memberGradeService.listByIds(gradeUids);
        }
        if (tagUids.size() > 0) {
            tagList = memberTagService.listByIds(tagUids);
        }
        Map<String, RankEntity> rankMap = new HashMap<>();
        Map<String, MemberGradeEntity> gradeMap = new HashMap<>();
        Map<String, MemberTagEntity> tagMap = new HashMap<>();

        rankList.forEach(item -> {
            rankMap.put(item.getUid(), item);
        });

        gradeList.forEach(item -> {
            gradeMap.put(item.getUid(), item);
        });

        tagList.forEach(item -> {
            tagMap.put(item.getUid(), item);
        });

        for (RankMemberEntity item : list) {
            // 设置点赞相关信息
            RankPraiseRecordDto userPraiseRecordVO = new RankPraiseRecordDto();
            userPraiseRecordVO.setResourceUid(item.getUid());
            userPraiseRecordVO.setResourceType(ResourceTypeEnum.RANK_MEMBER.getType());
            Map<String, Object> praiseMap = rankPraiseRecordService.praisedCount(userPraiseRecordVO);
            item.setPraiseInfo(praiseMap);

            //设置分类
            if (StringUtils.isNotEmpty(item.getRankUid())) {
                item.setRank(rankMap.get(item.getRankUid()));
            }
            //获取等级
            if (StringUtils.isNotEmpty(item.getGradeUid())) {
                item.setGrade(gradeMap.get(item.getGradeUid()));
            }
            //获取标签
            if (StringUtils.isNotEmpty(item.getTagUid())) {
                List<String> tagUidsTemp = StringUtils.changeStringToString(item.getTagUid(), SysConf.FILE_SEGMENTATION);
                List<MemberTagEntity> tagListTemp = new ArrayList<MemberTagEntity>();

                tagUidsTemp.forEach(tag -> {
                    tagListTemp.add(tagMap.get(tag));
                });
                item.setTagList(tagListTemp);
            }

        }

        pageList.setRecords(list);
        return pageList;
    }

    /**
     * 按照推荐等级查询榜单成员数量
     *
     * @param level
     * @return
     */
    @Override
    public Integer countRankMemberByLevel(Integer level) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.LEVEL, level);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        return this.count(queryWrapper);
    }

    /**
     * 保存、并发布新增领域事件
     *
     * @param rankMemberDto
     * @return
     */
    @Override
    public Boolean addRankMemberByAdmin(RankMemberDto rankMemberDto) {
        RankMemberEntity rankMemberEntity = new RankMemberEntity();
        BeanUtils.copyProperties(rankMemberDto, rankMemberEntity);
        /**
         * 保存
         */
        Boolean isSave = this.save(rankMemberEntity);
        /**
         * 发布新增领域事件
         */
        if (isSave) {
            this.setRankMemberWithGradeAndRank(rankMemberEntity);
            RankMemberDto dto = new RankMemberDto();
            BeanUtils.copyProperties(rankMemberEntity, dto);
            domainEventUtil.publishEvent(EventAction.RANK_MEMBER_ADD, dto);
        }
        return isSave;
    }

    @Override
    public String uploadLocalRankMember(List<RankMemberDto> list)  {


        // 获取一个排序最高的博客分类和标签
        RankCategoryEntity rankCategoryEntity = rankCategoryService.getTopOne();
        MemberGradeEntity memberGradeEntity = memberGradeService.getTopOne();

        if (rankCategoryEntity == null || memberGradeEntity == null) {
            return ResultUtil.errorWithMessage("使用本地上传，请先确保榜单分类，榜单成员等级中含有数据");
        }

        List<RankMemberEntity> memberEntityList = list.stream().map(item -> {
            RankMemberEntity memberEntity = new RankMemberEntity();
            BeanUtils.copyProperties(item, memberEntity);
            return memberEntity;
        }).collect(Collectors.toList());
        // 批量添加博客
        this.saveBatch(memberEntityList);
        List<MemberContentEntity> contentEntityList = memberEntityList.stream().map(item -> {
            MemberContentEntity contentEntity = new MemberContentEntity();
            contentEntity.setContent(item.getContent());
            contentEntity.setMemberUid(item.getUid());
            return contentEntity;
        }).collect(Collectors.toList());
        memberContentService.saveBatch(contentEntityList);

        for (RankMemberEntity memberEntity : memberEntityList) {
            /**
             * 发布新增事件
             */
            context.publishEvent(new RankMemberAddEvent(memberEntity, true));
        }

        return ResultUtil.successWithMessage(MessageConf.INSERT_SUCCESS);
    }

    /**
     * 编辑榜单成员
     *
     * @param rankMemberDto
     * @return
     */
    @Override
    public String editRankMemberByAdmin(RankMemberDto rankMemberDto) {
        RankMemberEntity rankMember = this.getById(rankMemberDto.getUid());
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.LEVEL, rankMemberDto.getLevel());
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        Integer count = this.count(queryWrapper);
        if (rankMember != null) {
            //传递过来的和数据库中的不同，代表用户已经修改过等级了，那么需要将count数加1
            if (!rankMember.getLevel().equals(rankMemberDto.getLevel())) {
                count += 1;
            }
        } else {
            return ResultUtil.errorWithMessage("编辑的博客不存在");
        }

        // 未通过审核的文章，无法设置推荐
        if (rankMemberDto.getLevel() != null && rankMemberDto.getLevel() > 0 && !AuditStatusEnum.AGREE.equals(rankMember.getAuditStatus())) {
            return ResultUtil.errorWithMessage("文章未通过审核，无法设置推荐等级!");
        }

        Long currentLevelAllowCount = rankMemberDto.getCurrentLevelAllowCount();
        if (count > currentLevelAllowCount) {
            StringBuilder sb = new StringBuilder();

            //添加的时候进行判断
            switch (rankMemberDto.getLevel()) {
                case LevelEnum.FIRST: {
                    sb.append("一");
                }
                break;

                case LevelEnum.SECOND: {
                    sb.append("二");
                }
                break;

                case LevelEnum.THIRD: {
                    sb.append("三");
                }
                break;

                case LevelEnum.FOURTH: {
                    sb.append("四");
                }
                break;
                default: {

                }
            }
            if(sb.length()>0) {
                sb.append("级推荐不能超过" + currentLevelAllowCount + "个");
                return ResultUtil.errorWithMessage(sb.toString());
            }

        }
//        String addVerdictResult = addVerdict(count, rankMemberDto.getLevel(), currentLevelAllowCount);

        RankMemberEntity newRankMember = rankMember.buildRankMember(rankMemberDto, true, rankMemberDto.getAdminUid(), null);
        Boolean isSave = newRankMember.updateById();
        if (isSave) {
            RankMemberDto dto = new RankMemberDto();
            BeanUtils.copyProperties(newRankMember, dto);
            domainEventUtil.publishEvent(EventAction.RANK_MEMBER_EDIT, dto);
        }
        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    /**
     * 修改榜单成员等级
     *
     * @param rankMemberDto
     * @return
     */
    @Override
    public String updateRankMemberLevel(RankMemberDto rankMemberDto) {
        RankMemberEntity rankMember = this.getById(rankMemberDto.getUid());
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.LEVEL, rankMemberDto.getLevel());
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        Integer count = this.count(queryWrapper);
        if (rankMember != null) {
            //传递过来的和数据库中的不同，代表用户已经修改过等级了，那么需要将count数加1
            if (!rankMember.getLevel().equals(rankMemberDto.getLevel())) {
                count += 1;
            }
        } else {
            return ResultUtil.errorWithMessage("编辑的博客不存在");
        }

        // 未通过审核的文章，无法设置推荐
        if (rankMemberDto.getLevel() != null && rankMemberDto.getLevel() > 0 && !AuditStatusEnum.AGREE.equals(rankMember.getAuditStatus())) {
            return ResultUtil.errorWithMessage("文章未通过审核，无法设置推荐等级!");
        }

        if(null != rankMemberDto.getLevel() && (rankMemberDto.getLevel() != 0)) {
            Long currentLevelAllowCount = rankMemberDto.getCurrentLevelAllowCount();
            if (count > currentLevelAllowCount) {
                StringBuilder sb = new StringBuilder();

                //添加的时候进行判断
                switch (rankMemberDto.getLevel()) {
                    case LevelEnum.FIRST: {
                        sb.append("一");
                    }
                    break;

                    case LevelEnum.SECOND: {
                        sb.append("二");
                    }
                    break;

                    case LevelEnum.THIRD: {
                        sb.append("三");
                    }
                    break;

                    case LevelEnum.FOURTH: {
                        sb.append("四");
                    }
                    break;
                    default: {

                    }
                }
                if(sb.length()>0) {
                    sb.append("级推荐不能超过" + currentLevelAllowCount + "个");
                    return ResultUtil.errorWithMessage(sb.toString());
                }

            }
        }
//        String addVerdictResult = addVerdict(count, rankMemberDto.getLevel(), currentLevelAllowCount);

        RankMemberEntity newRankMember = new RankMemberEntity();
        newRankMember.setUid(rankMemberDto.getUid());
        newRankMember.setAdminUid(rankMemberDto.getAdminUid());
        newRankMember.setLevel(rankMemberDto.getLevel());

        Boolean isSave = newRankMember.updateById();
        if(isSave && null != rankMemberDto.getLevel()){
            redisUtil.delete(RedisConf.RANK_MEMBER_LEVEL + Constants.SYMBOL_COLON + rankMemberDto.getLevel());
        }
        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    @Override
    public String publishByAdmin(RankMemberDto rankMemberDto) {
        HttpServletRequest request = RequestHolder.getRequest();
        RankMemberEntity rankMember = this.getOne(new LambdaQueryWrapper<RankMemberEntity>()
                .eq(RankMemberEntity::getUid, rankMemberDto.getUid())
        );

        if (!ContributeSourceEnum.ADMIN_PUBLISH.equals(rankMemberDto.getRankMemberSource())) {
            // 判断用户是否能编辑博客
            Object userUid = request.getAttribute(SysConf.USER_UID);
            if (userUid == null) {
                throw new UpdateException("用户未登录，无法发布/下架文章");
            }
            if (!userUid.equals(rankMember.getCreateUserUid())) {
                throw new UpdateException("您无权发布/下架文章");
            }

        }
        /**
         * 空判
         */
        if (rankMember == null) {
            throw new UpdateException("未查询到博客信息,请刷新页面后操作");
        }
        /**
         * 审核判断
         */
        if (!AuditStatusEnum.AGREE.equals(rankMember.getAuditStatus())) {
            throw new UpdateException("博客未审核或审核未通过,无法进行发布操作");
        }
        rankMember.setIsPublish(rankMemberDto.getIsPublish());
        Boolean isSave = rankMember.updateById();
        if (isSave) {
            RankMemberDto dto = new RankMemberDto();
            BeanUtils.copyProperties(rankMember, dto);
            domainEventUtil.publishEvent(EventAction.RANK_MEMBER_PUBLISH, dto);
        }

        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    @Override
    public String editBatch(List<RankMemberDto> rankMemberDtoList) {
        if (rankMemberDtoList.size() <= 0) {
            return ResultUtil.errorWithMessage(MessageConf.PARAM_INCORRECT);
        }
        List<String> rankMemberUidList = new ArrayList<>();
        Map<String, RankMemberDto> rankMemberVOMap = new HashMap<>();
        rankMemberDtoList.forEach(item -> {
            rankMemberUidList.add(item.getUid());
            rankMemberVOMap.put(item.getUid(), item);
        });

        Collection<RankMemberEntity> rankMemberList = this.listByIds(rankMemberUidList);
        rankMemberList.forEach(rankMember -> {
            RankMemberDto rankMemberDto = rankMemberVOMap.get(rankMember.getUid());
            if (rankMemberDto != null) {
//                rankMember.setAuthor(rankMemberVO.getAuthor());
//                rankMember.setArticlesPart(rankMemberVO.getArticlesPart());
                rankMember.setMemberName(rankMemberDto.getMemberName());
                rankMember.setSummary(rankMemberDto.getSummary());
//                rankMember.setContent(rankMemberVO.getContent());
                rankMember.setTagUid(rankMemberDto.getTagUid());
                rankMember.setRankUid(rankMemberDto.getRankUid());
                rankMember.setCatUid(rankMemberDto.getCatUid());
                rankMember.setFileUid(rankMemberDto.getFileUid());
                rankMember.setGradeUid(rankMemberDto.getGradeUid());
//                rankMember.setIsOriginal(rankMemberVO.getIsOriginal());
                rankMember.setIsPublish(rankMemberDto.getIsPublish());

                RankCategoryEntity rankCategoryEntity = new RankCategoryEntity();
                BeanUtils.copyProperties(rankMemberDto.getCategory(), rankCategoryEntity);
                rankMember.setCategory(rankCategoryEntity);

                RankEntity rankEntity = new RankEntity();
                BeanUtils.copyProperties(rankMemberDto.getRank(), rankEntity);
                rankMember.setRank(rankEntity);
                rankMember.setRankUid(rankEntity.getUid());
                rankMember.setRankName(rankEntity.getRankName());
//                rankMember.setOutsideLink(rankMemberVO.getOutsideLink());
                rankMember.setStatus(StatusEnum.ENABLE);
            }
        });
        Boolean save = this.updateBatchById(rankMemberList);
        //保存成功后，需要发送消息到solr 和 redis
        if (save) {
            Map<String, Object> map = new HashMap<>();
            map.put(SysConf.COMMAND, SysConf.EDIT_BATCH);
            //发送到RabbitMq
            rabbitTemplate.convertAndSend(SysConf.EXCHANGE_DIRECT, SysConf.DIDIOK_RANK_MEMBER, map);
        }

        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    @Override
    public String deleteRankMemberByAdmin(RankMemberDto rankMemberDto) {
        RankMemberEntity rankMember = this.getById(rankMemberDto.getUid());
        rankMember.setAuditStatus(AuditStatusEnum.REJECT);
        rankMember.setIsPublish(PublishEnum.NO_PUBLISH);
        rankMember.setStatus(StatusEnum.DISABLED);
        Boolean save = rankMember.updateById();

        //保存成功后，需要发送消息到solr 和 redis, 同时从专题管理Item中移除该博客
        if (save) {
            // 发布删除事件
            RankMemberDto dto = new RankMemberDto();
            BeanUtils.copyProperties(rankMember, dto);
            domainEventUtil.publishEvent(EventAction.RANK_MEMBER_DELETE, dto);
        }
        return ResultUtil.successWithMessage(MessageConf.DELETE_SUCCESS);
    }

    @Override
    public String deleteBatchRankMember(List<RankMemberDto> rankMemberDtoList) {
        if (rankMemberDtoList.size() <= 0) {
            return ResultUtil.errorWithMessage(MessageConf.PARAM_INCORRECT);
        }
        List<String> uidList = new ArrayList<>();
        StringBuffer uidSbf = new StringBuffer();
        rankMemberDtoList.forEach(item -> {
            uidList.add(item.getUid());
            uidSbf.append(item.getUid() + SysConf.FILE_SEGMENTATION);
        });
        Collection<RankMemberEntity> rankMemberList = this.listByIds(uidList);

        rankMemberList.forEach(item -> {
            item.setStatus(StatusEnum.DISABLED);
        });

        Boolean save = this.updateBatchById(rankMemberList);
        // 批量发送删除事件
        if (save) {
            for (RankMemberEntity rankMember : rankMemberList) {
                // 发布删除事件
                context.publishEvent(new RankMemberDeleteEvent(rankMember, true));
            }
        }


        return ResultUtil.successWithMessage(MessageConf.DELETE_SUCCESS);
    }

    @Override
    public String auditRankMember(RankMemberDto rankMemberDto) {
        RankMemberEntity rankMember = this.getById(rankMemberDto.getUid());
        if (rankMember == null) {
            throw new QueryException("未查询到该文章");
        }

//        AdminDto admin = adminFeignClient.getAdminById(RequestHolder.getAdminUid());
        rankMember.setAuditStatus(rankMemberDto.getAuditStatus());
        rankMember.setRejectReason(rankMemberDto.getRejectReason());
        rankMember.setAuditName(rankMemberDto.getAuditName());
        this.updateById(rankMember);
        context.publishEvent(new RankMemberAuditEvent(this.setRankMemberInfo(rankMember), true));
        return ResultUtil.successWithMessage(MessageConf.OPERATION_SUCCESS);
    }

    @Override
    public String flushRankMemberSummary() {
        // 查询所有可用的榜单成员
        List<RankMemberEntity> rankMemberList = rankMemberDao.listRankMemberWithContent(StatusEnum.ENABLE);
        rankMemberList.forEach(item -> {
            // 设置简介
            String summary = StringUtils.dealContent(item.getContent());
            if (summary.length() < 190) {
                item.setSummary(summary);
            } else {
                item.setSummary(summary.substring(0, 190) + "...");
            }
        });
        Boolean isSave = this.saveOrUpdateBatch(rankMemberList);
        if (isSave) {
            return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
        } else {
            return ResultUtil.errorWithMessage(MessageConf.UPDATE_FAIL);
        }
    }

    /**
     * 批量同步榜单成员索引
     *
     * @return
     */
    @Override
    public String buildRankMemberAggDoc() {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(SQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        Page<RankMemberEntity> page = new Page<>();
        long pageSize = 20L;
        long currentPage = 1L;
        int successCount = 0;
        int failCount = 0;
        while (true) {
            page.setCurrent(currentPage);
            page.setSize(pageSize);
            IPage<RankMemberEntity> iPage = this.page(page, queryWrapper);
            List<RankMemberEntity> rankMemberList = iPage.getRecords();
            if (rankMemberList.size() == 0) {
                break;
            }
            rankMemberList = this.setRankAndGradeAndPictureByRankMemberList(rankMemberList);
            rankMemberList = this.convertRankMemberInfoList(rankMemberList);
            List<AggEsDoc> aggEsDocList = new ArrayList<>();
            for (RankMemberEntity rankMember : rankMemberList) {
                // 判断是否是推广链接，如果是的话，直接跳出
//                if (Constants.STR_ONE.equals(blog.getType())) {
//                    continue;
//                }
                RankMemberDto rankMemberDto = new RankMemberDto();
                BeanUtils.copyProperties(rankMember,rankMemberDto);
                AggEsDoc aggEsDoc = AggEsDocConvert.convertRankMember(rankMemberDto);
                aggEsDocList.add(aggEsDoc);
            }
            // 同步索引
            String result = searchFeignClient.batchCreateEsIndex(aggEsDocList);
            if (WebUtils.checkSuccess(result)) {
                successCount += rankMemberList.size();
            } else {
                failCount += rankMemberList.size();
            }
            log.info(result);
            currentPage++;
        }
        return String.format("同步索引执行完成，成功：%s 条，失败：%s 条", successCount, failCount);
    }

    @Override
    public IPage<RankMemberEntity> searchRankMemberByGrade(String gradeUid, Long currentPage, Long pageSize) {
        MemberGradeEntity grade = memberGradeService.getById(gradeUid);
        if (grade != null) {
            HttpServletRequest request = RequestHolder.getRequest();
            String ip = IpUtils.getIpAddr(request);
            //从Redis取出数据，判断该用户24小时内，是否点击过该标签
            String jsonResult = redisUtil.get(RedisConf.GRADE_CLICK + RedisConf.SEGMENTATION + ip + "#" + gradeUid);
            if (StringUtils.isEmpty(jsonResult)) {
                //给标签点击数增加
                int clickCount = grade.getClickCount() + 1;
                grade.setClickCount(clickCount);
                grade.updateById();
                //将该用户点击记录存储到redis中, 24小时后过期
                redisUtil.setEx(RedisConf.GRADE_CLICK + RedisConf.SEGMENTATION + ip + RedisConf.WELL_NUMBER + gradeUid, clickCount + "",
                        24, TimeUnit.HOURS);
            }
        }
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(currentPage);
        page.setSize(pageSize);

        queryWrapper.like(SQLConf.GRADE_UID, gradeUid);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(BaseSQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        queryWrapper.select(RankMemberEntity.class, i -> !i.getProperty().equals(SysConf.CONTENT));
        IPage<RankMemberEntity> pageList = this.page(page, queryWrapper);
        List<RankMemberEntity> list = pageList.getRecords();
        list = this.setRankAndGradeAndPictureByRankMemberList(list);
        pageList.setRecords(list);
        return pageList;
    }

    @Override
    public void deleteRedisByMemberTag() {
        // 删除Redis中博客分类下的博客数量
        redisUtil.delete(RedisConf.DASHBOARD + Constants.SYMBOL_COLON + RedisConf.MEMBER_COUNT_BY_TAG);
        // 删除博客相关缓存
        deleteRedisByRankMember();
    }


    // endregion
    /***************************** didiok-admin:end **************************/



    /***************************** didiok-web:start **************************/
    // region didiok-web

    @Override
    public IPage<RankMemberEntity> getPageListWithPicAndRank(RankMemberDto rankMemberDto) {
        //分页
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(rankMemberDto.getCurrentPage());
        page.setSize(rankMemberDto.getPageSize());

        if (StringUtils.isNotEmpty(rankMemberDto.getOrderByAscColumn())) {
            // 将驼峰转换成下划线
            String column = StringUtils.underLine(new StringBuffer(rankMemberDto.getOrderByAscColumn())).toString();
            rankMemberDto.setOrderBy(column + " asc");
        } else if (StringUtils.isNotEmpty(rankMemberDto.getOrderByDescColumn())) {
            // 将驼峰转换成下划线
            String column = StringUtils.underLine(new StringBuffer(rankMemberDto.getOrderByDescColumn())).toString();
            rankMemberDto.setOrderBy(column + " desc");
        } else {
            // 是否启动排序字段
            if (rankMemberDto.getUseSort() == 0) {
                // 未使用，默认按时间倒序
                rankMemberDto.setOrderBy(SQLConf.CREATE_TIME + " desc");
            } else {
                rankMemberDto.setOrderBy(SQLConf.SORT + " desc");
            }
        }

        Page<RankMemberEntity> pageList = rankMemberDao.queryPageWithAttrInfo(page, rankMemberDto);
        List<RankMemberEntity> list = pageList.getRecords();

        if (list.size() == 0) {
            return pageList;
        }

        final StringBuffer fileUids = new StringBuffer();
//        List<String> rankUids = new ArrayList<>();
//        List<String> tagUids = new ArrayList<>();
        List<String> rankMemberUids = new ArrayList<>();
//        List<String> userUidList = new ArrayList<>();
        Date nowDate = new Date();
        list.forEach(item -> {

            // 是否活动结束
            if(null != item.getEndTime()){
                item.setIsEnd(nowDate.after(item.getEndTime()) ? 1 : 0);
            }

            // 是否报名截止
            if(null != item.getApplyEndTime()) {
                item.setIsApplyEnd(nowDate.after(item.getApplyEndTime()) ? 1 : 0);
            }

            if (StringUtils.isNotEmpty(item.getFileUid())) {
                fileUids.append(item.getFileUid() + SysConf.FILE_SEGMENTATION);
            }
//            if (StringUtils.isNotEmpty(item.getRankUid())) {
//                rankUids.add(item.getRankUid());
//            }
//            if (StringUtils.isNotEmpty(item.getTagUid())) {
//                List<String> tagUidsTemp = StringUtils.changeStringToString(item.getTagUid(), SysConf.FILE_SEGMENTATION);
//                for (String itemTagUid : tagUidsTemp) {
//                    tagUids.add(itemTagUid);
//                }
//            }
//            userUidList.add(item.getCreateUserUid());
            rankMemberUids.add(item.getUid());
        });

        String pictureList = null;
        if (fileUids != null) {
            pictureList = fileFeignClient.getPicture(fileUids.toString(), SysConf.FILE_SEGMENTATION);
        }

        List<Map<String, Object>> picList = webUtil.getPictureMap(pictureList);
//        Collection<RankEntity> rankList = new ArrayList<>();
//        Collection<MemberTagEntity> tagList = new ArrayList<>();

//        if (rankUids.size() > 0) {
//            rankList = rankService.listByIds(rankUids);
//        }
//        if (tagUids.size() > 0) {
//            tagList = memberTagService.listByIds(tagUids);
//        }

//        Map<String, RankEntity> rankMap = new HashMap<>();
//        Map<String, MemberTagEntity> tagMap = new HashMap<>();
        Map<String, String> pictureMap = new HashMap<>();
//        R userMapResult= userFeignClient.getUserAvatarMapByIds(userUidList);
//        R userMapResult= userFeignClient.listUserByUids(userUidList);
//        Map<String, UserDto> userMap = null;
//        if (userMapResult.getCode() == 0) {
//            userMap = userMapResult.getData(new TypeReference<Map<String, UserDto>>(){});
//        }else {
//            throw new FeignException("feign调用异常（获取带头像的用户Map）：失败");
//        }

//        rankList.forEach(item -> {
//            rankMap.put(item.getUid(), item);
//        });

//        tagList.forEach(item -> {
//            tagMap.put(item.getUid(), item);
//        });

        picList.forEach(item -> {
            pictureMap.put(item.get(SQLConf.UID).toString(), item.get(SQLConf.URL).toString());
        });

        // 查询对应的属性信息 attrInfo


        for (RankMemberEntity item : list) {
            //设置分类
//            if (StringUtils.isNotEmpty(item.getRankUid())) {
//                item.setRank(rankMap.get(item.getRankUid()));
//            }
            //获取标签
//            if (StringUtils.isNotEmpty(item.getTagUid())) {
//                List<String> tagUidsTemp = StringUtils.changeStringToString(item.getTagUid(), SysConf.FILE_SEGMENTATION);
//                List<MemberTagEntity> tagListTemp = new ArrayList<MemberTagEntity>();
//
//                tagUidsTemp.forEach(tag -> {
//                    tagListTemp.add(tagMap.get(tag));
//                });
//                item.setTagList(tagListTemp);
//            }
            //获取图片
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                List<String> pictureUidsTemp = StringUtils.changeStringToString(item.getFileUid(), SysConf.FILE_SEGMENTATION);
                List<String> pictureListTemp = new ArrayList<>();

                pictureUidsTemp.forEach(picture -> {
                    pictureListTemp.add(pictureMap.get(picture));
                });
                // 只设置一张标题图
                if (pictureListTemp.size() > 0) {
                    item.setPhotoUrl(pictureListTemp.get(0));
                } else {
                    item.setPhotoUrl("");
                }
            }
//            item.setUser(userMap.get(item.getCreateUserUid()));
        }
        pageList.setRecords(list);
        return pageList;
    }

    /**
     * 新增榜单成员
     *
     * @param rankMemberDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String addRankMemberByUser(RankMemberDto rankMemberDto) {
        HttpServletRequest request = RequestHolder.getRequest();
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.LEVEL, rankMemberDto.getLevel());
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        Integer count = this.count(queryWrapper);
        // 判断插入博客的时候，会不会超过预期设置
        String addVerdictResult = this.addVerdict(count + 1, rankMemberDto.getLevel());
        // 判断是否能够添加推荐
        if (StringUtils.isNotBlank(addVerdictResult)) {
            return addVerdictResult;
        }
        /**
         * 当为用户投稿的时候
         */
        Object userUid = request.getAttribute(SysConf.USER_UID);
        /**
         * 查询当前用户
         */
        R result = userFeignClient.getUserById(userUid.toString());
        UserDto user;
        if (result.getCode() == 0) {
            user = result.getData(new TypeReference<UserDto>(){});
        }else {
            throw new FeignException("feign调用异常（根据用户id找用户）：失败");
        }
        /**
         * 是否是普通用户
         */
        Boolean isNormalUser = false;
        /**
         * 构建博客对象
         */
        //如果是原创，作者为用户的昵称
        RankMemberEntity rankMember = new RankMemberEntity();
        rankMember = rankMember.buildRankMember(rankMemberDto, false, userUid.toString(), user.getUserName());
        if (userUid == null) {
            return ResultUtil.errorWithMessage("用户未登录，无法投稿");
        }
        /**
         * 判断该用户是否超过今日投稿次数
         */
        Integer userMaxPublishCount = Integer.valueOf(adminFeignClient.getSysParamsValueByKey(SysConf.USER_PUBLISH_RANK_MEMBER_COUNT));
        String countJson = redisUtil.get(RedisConf.USER_PUBLISH_RANK_MEMBER_COUNT + Constants.SYMBOL_COLON + userUid);
        Integer userPublishCount = 0;
        if (StringUtils.isNotEmpty(countJson)) {
            userPublishCount = Integer.valueOf(countJson);
            if (userPublishCount >= userMaxPublishCount) {
                return ResultUtil.errorWithMessage("您发布文章次数已达今日上限");
            }
        }
        /**
         * 如果是选择发布的话 查看是否允许免审
         */
        if (PublishEnum.PUBLISH.equals(rankMember.getIsPublish())) {
            // 非普通用户，可直接免审核上架
            if (user != null && user.getUserTag() > Constants.NUM_ZERO) {
                rankMember.setAuditStatus(AuditStatusEnum.AGREE);
                rankMember.setAuditTime(new Date());
                isNormalUser = false;
            } else {
                rankMember.setAuditStatus(AuditStatusEnum.WAIT);
                isNormalUser = true;
            }
        } else {
            // 保存草稿，默认是
            rankMember.setAuditStatus(AuditStatusEnum.WAIT);
        }

        // 插入 rankMember
        Boolean isSave = this.save(rankMember);

        // 插入 attrInfo
        AttrInfoEntity attrInfoEntity = setAttrInfoByRankMember(rankMember.getUid(),userUid.toString(), user.getUserName(), rankMemberDto);
        attrInfoService.save(attrInfoEntity);

        /**
         * 保存成功才 ++;
         */
        if (isSave) {
            userPublishCount++;
            /**
             *   设置一天过期
             */
            redisUtil.setEx(RedisConf.USER_PUBLISH_RANK_MEMBER_COUNT + Constants.SYMBOL_COLON + userUid, JsonUtils.objectToJson(userPublishCount), 1, TimeUnit.DAYS);
        }


        if (isSave) {
            /**
             * 发布新增事件
             */
//            RankMemberEntity rankMemberEntity = this.setRankMemberInfoWithGradePicRank(rankMember);
            RankMemberDto memberDto = new RankMemberDto();
            BeanUtils.copyProperties(rankMember, memberDto);
            domainEventUtil.publishEvent(EventAction.RANK_MEMBER_ADD, memberDto);

            if (PublishEnum.PUBLISH.equals(rankMember.getIsPublish())) {
                // 普通用户，提示需要审核
                if (isNormalUser) {
                    return ResultUtil.successWithMessage("博客提交成功，请等待管理员审核后上架~");
                } else {
                    // vip用户，直接免审
                    return ResultUtil.successWithMessage("博客发布成功，可以在 个人中心->我的博客，进行查看");
                }
            } else if (PublishEnum.NO_PUBLISH.equals(rankMember.getIsPublish())) {
                return ResultUtil.successWithMessage("保存草稿成功，可以在 个人中心->我的博客，进行提交发布！");
            }
        }


        return ResultUtil.successWithMessage(MessageConf.INSERT_SUCCESS);
    }

    /**
     * 根据 rankMember 的数据生成 AttrInfoEntity 数据
     * @param rankMember
     * @return
     */
    private AttrInfoEntity setAttrInfoByRankMember(String memberUid, String createUserUid, String createUserName, RankMemberDto rankMember) {
        AttrInfoEntity attrInfoEntity = new AttrInfoEntity();
        attrInfoEntity.setMemberUid(memberUid);
        attrInfoEntity.setMemberName(rankMember.getTitle());
        attrInfoEntity.setProvince(rankMember.getProvince());
        attrInfoEntity.setProvinceCode(rankMember.getProvinceCode());
        attrInfoEntity.setCity(rankMember.getCity());
        attrInfoEntity.setCityCode(rankMember.getCityCode());
        attrInfoEntity.setDistrict(rankMember.getDistrict());
        attrInfoEntity.setDistrictCode(rankMember.getDistrictCode());
        attrInfoEntity.setAddress(rankMember.getAddress());
        attrInfoEntity.setStartTime(rankMember.getStartTime());
        attrInfoEntity.setEndTime(rankMember.getEndTime());
        attrInfoEntity.setApplyEndTime(rankMember.getApplyEndTime());
        attrInfoEntity.setPrice(rankMember.getPrice());
        attrInfoEntity.setAllowPeopleNum(rankMember.getAllowPeopleNum());
        attrInfoEntity.setRemark(rankMember.getRemark());
        attrInfoEntity.setWeChat(rankMember.getWeChat());
        attrInfoEntity.setPhone(rankMember.getPhone());
        attrInfoEntity.setLongitude(rankMember.getLongitude());
        attrInfoEntity.setLatitude(rankMember.getLatitude());
        attrInfoEntity.setCreateUserUid(createUserUid);
        attrInfoEntity.setCreateUserName(createUserName);

        // 领队
        attrInfoEntity.setAllowLeaderNum(rankMember.getAllowLeaderNum());
        attrInfoEntity.setLeaderSalary(rankMember.getLeaderSalary());
        attrInfoEntity.setLeaderTask(rankMember.getLeaderTask());
        attrInfoEntity.setLeaderCondition(rankMember.getLeaderCondition());
        attrInfoEntity.setLeaderRemark(rankMember.getLeaderRemark());
        attrInfoEntity.setLeaderApplyEndTime(rankMember.getLeaderApplyEndTime());
        return attrInfoEntity;
    }

    /**
     * 普通用户编辑博客
     *
     * @param rankMemberDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String editRankMemberByUser(RankMemberDto rankMemberDto) {

        HttpServletRequest request = RequestHolder.getRequest();
        /**
         * 判断用户是否能编辑博客
         */
        Object userUid = request.getAttribute(SysConf.USER_UID);
        if (userUid == null) {
            throw new UpdateException("用户未登录，无法编辑文章");
        }
        RankMemberEntity rankMember = this.getById(rankMemberDto.getUid());
        if (!userUid.equals(rankMember.getCreateUserUid())) {
            throw new UpdateException("您无权编辑其它用户的文章");
        }

        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.LEVEL, rankMemberDto.getLevel());
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        Integer count = this.count(queryWrapper);
        if (rankMember != null) {
            //传递过来的和数据库中的不同，代表用户已经修改过等级了，那么需要将count数加1
            if (!rankMember.getLevel().equals(rankMemberDto.getLevel())) {
                count += 1;
            }
        }
        /**
         * 查询当前用户
         */
        R result = userFeignClient.getUserById(userUid.toString());
        UserDto user;
        if (result.getCode() == 0) {
            user = result.getData(new TypeReference<UserDto>(){});
        }else {
            throw new FeignException("feign调用异常（根据用户id找用户）：失败");
        }
        /**
         * 是否是普通用户
         */
        Boolean isNormalUser = false;
        String addVerdictResult = addVerdict(count, rankMemberDto.getLevel());
        //添加的时候进行判断
        if (StringUtils.isNotBlank(addVerdictResult)) {
            return addVerdictResult;
        }
        //组装数据
        RankMemberEntity newRankMember = rankMember.buildRankMember(rankMemberDto, false, userUid.toString(), request.getAttribute(SysConf.USER_NAME).toString());
        newRankMember.setUid(rankMember.getUid());

        /**
         * 当修改之后 要求上架
         */
        if (PublishEnum.PUBLISH.equals(newRankMember.getIsPublish())) {
            /**
             * 原博客 审核状态如果不是 未审核
             * 需要将审核状态初始为未审核
             */
            // 非普通用户，可直接免审核上架
            if (user != null && user.getUserTag() > Constants.NUM_ZERO) {
                newRankMember.setAuditStatus(AuditStatusEnum.AGREE);
                newRankMember.setAuditTime(new Date());
                isNormalUser = false;
            } else {
                newRankMember.setAuditStatus(AuditStatusEnum.WAIT);
                isNormalUser = true;
            }
        }

        Boolean isSave = newRankMember.updateById();

        // 首先删除当前 rankMember 下的 attrInfo
        attrInfoService.updateStatusByMemberUid(rankMember.getUid(), StatusEnum.DISABLED);
        // 然后插入 attrInfo
        AttrInfoEntity attrInfoEntity = setAttrInfoByRankMember(rankMember.getUid(),userUid.toString(), user.getUserName(), rankMemberDto);
        attrInfoService.save(attrInfoEntity);

        /**
         * 发布修改事件
         */
        RankMemberDto dto = new RankMemberDto();
        BeanUtils.copyProperties(newRankMember, dto);
        domainEventUtil.publishEvent(EventAction.RANK_MEMBER_EDIT, dto);
        if (isSave && PublishEnum.PUBLISH.equals(newRankMember.getIsPublish())) {

            if (isNormalUser) {
                return ResultUtil.successWithMessage("博客提交成功，请等待管理员审核后上架~");
            } else {
                return ResultUtil.successWithMessage("博客发布成功，可以在 个人中心->我的博客，进行查看");
            }
        }
        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    /**
     * 普通用户 发布/下架 博客
     *
     * @param rankMemberDto
     * @return
     */
    @Override
    public String publishByUser(RankMemberDto rankMemberDto) {
        HttpServletRequest request = RequestHolder.getRequest();
        RankMemberEntity rankMember = this.getOne(new LambdaQueryWrapper<RankMemberEntity>()
                .eq(RankMemberEntity::getUid, rankMemberDto.getUid())
        );
        // 判断用户是否能编辑博客
        Object userUid = request.getAttribute(SysConf.USER_UID);
        if (userUid == null) {
            throw new UpdateException("用户未登录，无法发布/下架文章");
        }
        if (!userUid.equals(rankMember.getCreateUserUid())) {
            throw new UpdateException("您无权发布/下架文章");
        }
        /**
         * 空判
         */
        if (rankMember == null) {
            throw new UpdateException("未查询到博客信息,请刷新页面后操作");
        }
        /**
         * 要求上架
         */
        if (PublishEnum.PUBLISH.equals(rankMemberDto.getIsPublish())) {
            /**
             * 查询当前用户
             */
            R result = userFeignClient.getUserById(userUid.toString());
            UserDto user;
            if (result.getCode() == 0) {
                user = result.getData(new TypeReference<UserDto>(){});
            }else {
                throw new FeignException("feign调用异常（根据用户id找用户）：失败");
            }
            /**
             * 非普通用户，可直接免审核上架
             */
            if (user != null && user.getUserTag() > Constants.NUM_ZERO) {
                rankMember.setAuditStatus(AuditStatusEnum.AGREE);
                rankMember.setAuditTime(new Date());
            }
        }
        /**
         * 审核判断
         */
        if (!AuditStatusEnum.AGREE.equals(rankMember.getAuditStatus())) {
            throw new UpdateException("博客未审核或审核未通过,无法进行发布操作");
        }
        rankMember.setIsPublish(rankMemberDto.getIsPublish());

        Boolean isSave = rankMember.updateById();
        if (isSave) {
            /**
             * 发布上下架事件
             */
            RankMemberDto dto = new RankMemberDto();
            BeanUtils.copyProperties(rankMember, dto);
            domainEventUtil.publishEvent(EventAction.RANK_MEMBER_PUBLISH, dto);
        }
        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    /**
     * 普通用户 将活动取消/恢复正常
     *
     * @param rankMemberDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String changeActivityStatus(RankMemberDto rankMemberDto) {
        HttpServletRequest request = RequestHolder.getRequest();
        RankMemberEntity rankMember = this.getOne(new LambdaQueryWrapper<RankMemberEntity>()
                .eq(RankMemberEntity::getUid, rankMemberDto.getUid())
        );
        // 判断用户是否能编辑博客
        Object userUid = request.getAttribute(SysConf.USER_UID);
        if (userUid == null) {
            throw new UpdateException("用户未登录，无法将活动取消/恢复正常");
        }
        if (!userUid.equals(rankMember.getCreateUserUid())) {
            throw new UpdateException("您无权将活动取消/恢复正常");
        }
        /**
         * 空判
         */
        if (rankMember == null) {
            throw new UpdateException("未查询到博客信息,请刷新页面后操作");
        }

        rankMember.setActivityStatus(rankMemberDto.getActivityStatus());

        Boolean isSave = rankMember.updateById();
//        if (isSave) {
//            /**
//             * 活动取消/恢复正常 事件
//             */
//            RankMemberDto dto = new RankMemberDto();
//            BeanUtils.copyProperties(rankMember, dto);
//            domainEventUtil.publishEvent(EventAction.RANK_MEMBER_ACTIVITY_STATUS_CHANGE, dto);
//        }
        // 将该活动对应的所有报名订单取消
        if(ActivityStatusEnum.CANCEL.getCode().equals(rankMemberDto.getActivityStatus())){
            String jsonStr = payFeignClient.cancelPayOrderByResourceUid(rankMemberDto.getUid());

            Map<String, Object> dataMap = (Map<String, Object>) JsonUtils.jsonToObject(jsonStr, Map.class);
            if (!BaseSysConf.SUCCESS.equals(dataMap.get(BaseSysConf.CODE))) {
                throw new FeignException("feign调用异常：取消此活动对应的的报名订单失败");
            }
        }

        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    /**
     * 普通用户 删除博客
     *
     * @param rankMemberDto
     * @return
     */
    @Override
    public String deleteRankMemberByUser(RankMemberDto rankMemberDto) {
        // 判断用户是否能编辑博客
        HttpServletRequest request = RequestHolder.getRequest();
        // 判断用户是否能编辑博客
        Object userUid = request.getAttribute(SysConf.USER_UID);
        if (userUid == null) {
            throw new UpdateException("用户未登录，无法发布/下架文章");
        }

        RankMemberEntity blog = this.getById(rankMemberDto.getUid());
        if (!userUid.equals(blog.getCreateUserUid())) {
            throw new UpdateException("您无权删除其它用户的文章");
        }
        blog.setStatus(StatusEnum.DISABLED);
        Boolean save = blog.updateById();

        //保存成功后，需要发送消息到solr 和 redis, 同时从专题管理Item中移除该博客
        if (save) {
            /**
             * 发布删除事件
             */
            RankMemberDto dto = new RankMemberDto();
            BeanUtils.copyProperties(blog, dto);
            domainEventUtil.publishEvent(EventAction.RANK_MEMBER_DELETE, dto);
        }

        return ResultUtil.successWithMessage(MessageConf.DELETE_SUCCESS);
    }

    @Override
    public RankMemberEntity randomRankMember() {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        Integer rankMemberCount = this.count(queryWrapper);
        Integer currentPage = RandomUtil.randomInt(rankMemberCount);
        Page<RankMemberEntity> page = new Page<>();
        page.setSize(1);
        page.setCurrent(currentPage);
        IPage<RankMemberEntity> problemIPage = this.page(page, queryWrapper);
        if (problemIPage.getRecords().size() > 0) {
            // 返回第一个元素
            RankMemberEntity rankMember = problemIPage.getRecords().get(0);
            rankMember.setContent("");
            return rankMember;
        }
        return null;
    }

    /**
     * 查询动态排行榜
     *
     * @return
     */
    @Override
    public List<RankMemberEntity> getLeaderRankMember(Boolean refresh) {

        String rankBlogListJson = redisUtil.get(RedisConf.TOP_LIST + Constants.SYMBOL_COLON + RedisConf.TOP_RANK_MEMBER_LIST);
        List<RankMemberEntity> leaders;
        if (StringUtils.isNotEmpty(rankBlogListJson) && refresh) {
            leaders = JsonUtils.jsonToList(rankBlogListJson, RankMemberEntity.class);
        } else {
            QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("user_uid, count(uid) as sumCredits ");
            queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
            queryWrapper.eq(SQLConf.IS_PUBLISH, StatusEnum.ENABLE);
            queryWrapper.isNotNull(SQLConf.USER_UID);
            queryWrapper.groupBy(SQLConf.USER_UID);
            queryWrapper.orderByDesc(SQLConf.SUM_CREDITS);
            queryWrapper.last("limit 10");
            leaders = this.list(queryWrapper);

            List<String> userIds = new ArrayList<>();
            leaders.forEach((item) -> {
                userIds.add(item.getCreateUserUid());
            });

            // 获取用户列表
            Map<String, UserDto> userMap = this.usersConvert(userIds);

            leaders.forEach((item) -> {
                item.setUser(userMap.get(item.getCreateUserUid()));
            });
            redisUtil.setEx(RedisConf.TOP_LIST + Constants.SYMBOL_COLON + RedisConf.TOP_RANK_MEMBER_LIST, JsonUtils.objectToJson(leaders), 24, TimeUnit.HOURS);
        }
        return leaders;
    }

    @Override
    public IPage<RankMemberEntity> getRankMemberPageByLevel(Integer level, Long currentPage, Integer useSort) {

        //从Redis中获取内容
        String jsonResult = redisUtil.get(RedisConf.RANK_MEMBER_LEVEL + RedisConf.SEGMENTATION + level);

        //判断redis中是否有文章
        if (StringUtils.isNotEmpty(jsonResult)) {
            List jsonResult2List = JsonUtils.jsonArrayToArrayList(jsonResult);
            IPage pageList = new Page();
            pageList.setRecords(jsonResult2List);
            return pageList;
        }
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(currentPage);
        // 为了提升代码速度，这里直接写死吧
        Long rankMemberCount = DefaultConstants.RANK_MEMBER_FIRST_COUNT;
        page.setSize(rankMemberCount);
        // 为了提升代码速度，下面的直接注释掉
//        String rankMemberCount = null;
//        switch (level) {
//            case LevelEnum.NORMAL: {
//                rankMemberCount = adminFeignClient.getSysParamsValueByKey(SysConf.RANK_MEMBER_NEW_COUNT);
//            }
//            break;
//            case LevelEnum.FIRST: {
//                rankMemberCount = adminFeignClient.getSysParamsValueByKey(SysConf.RANK_MEMBER_FIRST_COUNT);
//            }
//            break;
//            case LevelEnum.SECOND: {
//                rankMemberCount = adminFeignClient.getSysParamsValueByKey(SysConf.RANK_MEMBER_SECOND_COUNT);
//            }
//            break;
//            case LevelEnum.THIRD: {
//                rankMemberCount = adminFeignClient.getSysParamsValueByKey(SysConf.RANK_MEMBER_THIRD_COUNT);
//            }
//            break;
//            case LevelEnum.FOURTH: {
//                rankMemberCount = adminFeignClient.getSysParamsValueByKey(SysConf.RANK_MEMBER_FOURTH_COUNT);
//            }
//            break;
//        }
//        if (StringUtils.isEmpty(rankMemberCount)) {
//            log.error(MessageConf.PLEASE_CONFIGURE_SYSTEM_PARAMS);
//        } else {
//            page.setSize(Long.valueOf(rankMemberCount));
//        }

        IPage<RankMemberEntity> pageList = this.getRankMemberPageByLevel(page, level, useSort);
        List<RankMemberEntity> list = pageList.getRecords();

        // 一级推荐或者二级推荐没有内容时，自动把top5填充至一级推荐和二级推荐中 【暂时关闭自动填充】
//        if ((level == SysConfConstant.ONE || level == SysConfConstant.TWO) && list.size() == 0) {
//            QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
//            Page<RankMemberEntity> hotPage = new Page<>();
//            hotPage.setCurrent(1);
//            String rankMemberHotCount = sysParamsService.getSysParamsValueByKey(SysConfConstant.BLOG_HOT_COUNT);
//            String rankMemberSecondCount = sysParamsService.getSysParamsValueByKey(SysConfConstant.BLOG_SECOND_COUNT);
//            if (StringUtils.isEmpty(rankMemberHotCount) || StringUtils.isEmpty(rankMemberSecondCount)) {
//                log.error(MessageConfConstant.PLEASE_CONFIGURE_SYSTEM_PARAMS);
//            } else {
//                hotPage.setSize(Long.valueOf(rankMemberHotCount));
//            }
//            queryWrapper.eq(SQLConfConstant.STATUS, EStatus.ENABLE);
//            queryWrapper.eq(SQLConfConstant.IS_PUBLISH, EPublish.PUBLISH);
//            queryWrapper.orderByDesc(SQLConfConstant.CLICK_COUNT);
//            queryWrapper.select(RankMemberEntity.class, i -> !i.getProperty().equals(SQLConfConstant.CONTENT));
//            IPage<RankMemberEntity> hotPageList = this.page(hotPage, queryWrapper);
//            List<RankMemberEntity> hotBlogList = hotPageList.getRecords();
//            List<RankMemberEntity> secondBlogList = new ArrayList<>();
//            List<RankMemberEntity> firstBlogList = new ArrayList<>();
//            for (int a = 0; a < hotBlogList.size(); a++) {
//                // 当推荐大于两个的时候
//                if ((hotBlogList.size() - firstBlogList.size()) > Long.valueOf(rankMemberSecondCount)) {
//                    firstBlogList.add(hotBlogList.get(a));
//                } else {
//                    secondBlogList.add(hotBlogList.get(a));
//                }
//            }
//
//            firstBlogList = setBlog(firstBlogList);
//            secondBlogList = setBlog(secondBlogList);
//
//            // 将从数据库查询的数据缓存到redis中，设置1小时后过期 [避免 list 中没有数据而保存至 redis 的情况]
//            if (firstBlogList.size() > 0) {
//                redisUtil.setEx(RedisConfConstant.BLOG_LEVEL + Constants.SYMBOL_COLON + Constants.NUM_ONE, JsonUtils.objectToJson(firstBlogList), 1, TimeUnit.HOURS);
//            }
//            if (secondBlogList.size() > 0) {
//                redisUtil.setEx(RedisConfConstant.BLOG_LEVEL + Constants.SYMBOL_COLON + Constants.NUM_TWO, JsonUtils.objectToJson(secondBlogList), 1, TimeUnit.HOURS);
//            }
//
//            switch (level) {
//                case SysConfConstant.ONE: {
//                    pageList.setRecords(firstBlogList);
//                }
//                break;
//                case SysConfConstant.TWO: {
//                    pageList.setRecords(secondBlogList);
//                }
//                break;
//            }
//            return pageList;
//        }


        list = setRankMemberInfoWithPhotoUrl(list);
        pageList.setRecords(list);

        // 将从数据库查询的数据缓存到redis中 [避免 list 中没有数据而保存至 redis 的情况]
        if (list.size() > 0) {
            redisUtil.setEx(SysConf.RANK_MEMBER_LEVEL + SysConf.REDIS_SEGMENTATION + level, JsonUtils.objectToJson(list), 1, TimeUnit.HOURS);
        }
        return pageList;
    }

    @Override
    public IPage<RankMemberEntity> getHotRankMember() {
        // 前台  查看当前用户 是否是特权用户
//        double userTag = RequestHolder.getUserTag();

        //从Redis中获取内容
        String jsonResult = redisUtil.get(RedisConf.HOT_RANK_MEMBER);
        //判断redis中是否有文章
        if (StringUtils.isNotEmpty(jsonResult)) {
            List jsonResult2List = JsonUtils.jsonArrayToArrayList(jsonResult);
            IPage pageList = new Page();
            pageList.setRecords(jsonResult2List);
            return pageList;
        }
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(0);
        String rankMemberHotCount = adminFeignClient.getSysParamsValueByKey(SysConf.RANK_MEMBER_HOT_COUNT);
        if (StringUtils.isEmpty(rankMemberHotCount)) {
            log.error(MessageConf.PLEASE_CONFIGURE_SYSTEM_PARAMS);
        } else {
            page.setSize(Long.valueOf(rankMemberHotCount));
        }

        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.orderByDesc(SQLConf.CLICK_COUNT);
        //因为首页并不需要显示内容，所以需要排除掉内容字段
        queryWrapper.select(RankMemberEntity.class, i -> !i.getProperty().equals(SQLConf.CONTENT));
        IPage<RankMemberEntity> pageList = this.page(page, queryWrapper);
        List<RankMemberEntity> list = pageList.getRecords();
        list = setRankMemberInfoWithGradePicRankBatch(list);
        pageList.setRecords(list);
        // 将从数据库查询的数据缓存到redis中[避免list中没有数据而保存至redis的情况]
        if (list.size() > 0) {
            redisUtil.setEx(RedisConf.HOT_RANK_MEMBER, JsonUtils.objectToJson(list), 1, TimeUnit.HOURS);
        }
        return pageList;
    }

    @Override
    public IPage<RankMemberEntity> getNewRankMember(RankMemberDto rankMemberVO) {
        Long rankMemberNewCount = DefaultConstants.RANK_MEMBER_NEW_COUNT;
        // 只查询2条
        rankMemberVO.setPageSize(rankMemberNewCount);
        // 最新创建：按照创建时间排序
        rankMemberVO.setActivityOrderBy(ActivityOrderByEnum.LATEST_RELEASE.getCode());
        rankMemberVO.setAuditStatus(AuditStatusEnum.AGREE);
        rankMemberVO.setIsPublish(PublishEnum.PUBLISH);
        rankMemberVO.setStatus(StatusEnum.ENABLE);

        // 查询
        return getRankMemberPageList(rankMemberVO);

//        // 判断Redis中是否缓存了第一页的内容
//        if (currentPage == 1L) {
//            //从Redis中获取内容
//            String jsonResult = redisUtil.get(RedisConf.NEW_BLOG);
//            //判断redis中是否有文章
//            if (StringUtils.isNotEmpty(jsonResult)) {
//                IPage pageList = JsonUtils.jsonToPojo(jsonResult, Page.class);
//                return pageList;
//            }
//        }

        //将从最新博客缓存到redis中
//        if (currentPage == 1L) {
//            redisUtil.setEx(RedisConfConstant.NEW_BLOG, JsonUtils.objectToJson(pageList), 1, TimeUnit.HOURS);
//        }
    }

    @Override
    public IPage<RankMemberEntity> getRankMemberBySearch(Long currentPage, Long pageSize) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(currentPage);
        String rankMemberNewCount = adminFeignClient.getSysParamsValueByKey(SysConf.RANK_MEMBER_NEW_COUNT);
        if (StringUtils.isEmpty(rankMemberNewCount)) {
            log.error(MessageConf.PLEASE_CONFIGURE_SYSTEM_PARAMS);
        } else {
            page.setSize(Long.valueOf(rankMemberNewCount));
        }
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(BaseSQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        IPage<RankMemberEntity> pageList = this.page(page, queryWrapper);
        List<RankMemberEntity> list = pageList.getRecords();
        if (list.size() <= 0) {
            return pageList;
        }
        list = setRankMemberInfoWithGradePicRankBatch(list);
        pageList.setRecords(list);
        return pageList;
    }

    @Override
    public IPage<RankMemberEntity> getRankMemberByTime(Long currentPage, Long pageSize) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(currentPage);
        page.setSize(pageSize);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(BaseSQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        //因为首页并不需要显示内容，所以需要排除掉内容字段
        queryWrapper.select(RankMemberEntity.class, i -> !i.getProperty().equals(SQLConf.CONTENT));
        IPage<RankMemberEntity> pageList = this.page(page, queryWrapper);
        List<RankMemberEntity> list = pageList.getRecords();
        list = setRankMemberInfoWithGradePicRankBatch(list);
        pageList.setRecords(list);
        return pageList;
    }

    /**
     * 给博客设置等级、分类和头像
     *
     * @param rankMember@return
     */
    @Override
    public RankMemberEntity setRankMemberInfoWithGradePicRank(RankMemberEntity rankMember) {
        String fileUid = rankMember.getFileUid();
        String gradeUid = rankMember.getGradeUid();
        String rankUid = rankMember.getRankUid();
        String userUid = null;
        String adminUid = null;
        // 判断用户投稿，还是后台管理员添加
        if (ContributeSourceEnum.USER_PUBLISH.equals(rankMember.getRankMemberSource())) {
            if (StringUtils.isNotEmpty(rankMember.getCreateUserUid())) {
                userUid = rankMember.getCreateUserUid();
                R userResult = userFeignClient.getUserListAndAvatarById(userUid);
                UserDto user;
                if (userResult.getCode() == 0) {
                    user = userResult.getData(new TypeReference<UserDto>(){});
                }else {
                    throw new FeignException("feign调用异常（通过id获取用户【携带用户头像和背景图片】）：失败");
                }
                rankMember.setUser(user);
            }
        } else {
            if (StringUtils.isNotEmpty(rankMember.getAdminUid())) {
                adminUid = rankMember.getAdminUid();
                R adminResult = adminFeignClient.getAdminByUid(adminUid);
                AdminDto admin = null;
                if (adminResult.getCode() == 0) {
                    admin = adminResult.getData(new TypeReference<AdminDto>(){});
                }else {
                    throw new FeignException("feign调用异常（通过 id 获取管理员）：失败");
                }
                UserDto user = new UserDto();
                if (admin != null) {
                    user.setAvatar(admin.getAvatar());
                    user.setUid(admin.getUid());
                    user.setOccupation(admin.getOccupation());
                    user.setGender(admin.getGender());
                    user.setSummary(admin.getSummary());
                    user.setNickname(admin.getNickname());
                    user.setPhotoUrl(admin.getPhotoUrl());
                    rankMember.setUser(user);
                }
            }
        }

        Map<String, String> pictureMap = fileFeignUtil.fileUidToFileUrlMap(Collections.singletonList(fileUid));

        //设置等级
        if (StringUtils.isNotEmpty(gradeUid)) {
            MemberGradeEntity grade = memberGradeService.getById(gradeUid);
            rankMember.setGrade(grade);
        }

        //设置榜单
        if (StringUtils.isNotEmpty(rankMember.getRankUid())) {
            RankEntity rank = rankService.getById(rankUid);
            rankMember.setRank(rank);
        }

        //获取图片
        if (StringUtils.isNotEmpty(fileUid)) {
            List<String> pictureUidsTemp = StringUtils.changeStringToString(fileUid, SysConf.FILE_SEGMENTATION);
            List<String> pictureListTemp = new ArrayList<>();

            pictureUidsTemp.forEach(picture -> {
                pictureListTemp.add(pictureMap.get(picture));
            });
            rankMember.setPhotoList(pictureListTemp);
        }

        return rankMember;
    }

    /**
     * 给博客设置分类和用户信息
     *
     * @param rankMember@return
     */
    @Override
    public RankMemberEntity setRankMemberInfoWithUser(RankMemberEntity rankMember) {

        UserDto user = null;
        // 查询用户信息
        if (StringUtils.isNotEmpty(rankMember.getCreateUserUid())) {

            R result = userFeignClient.getUserById(rankMember.getCreateUserUid());
            UserDto userResult;
            if(result.getCode()==0){
                userResult = result.getData(new TypeReference<UserDto>(){});
            }else {
                throw new FeignException("feign调用异常（根据用户id找用户）：失败");
            }
            if (null != userResult) {
                // 过滤用户敏感信息
                user = this.convertUser(userResult);
            }
        }

        List<String> fileUidList = new ArrayList<>();
        if (user != null && StringUtils.isNotEmpty(user.getAvatar())) {
            fileUidList.add(user.getAvatar());
        }
        String fileUid = rankMember.getFileUid();
        if(StringUtils.isNotEmpty(fileUid)) {
            fileUidList.add(fileUid);
        }
        // 调用didiok-file接口查询图片
        Map<String, String> pictureMap = fileFeignUtil.fileUidToFileUrlMap(fileUidList);
        if (user != null && StringUtils.isNotEmpty(user.getAvatar())) {
            String avatar = user.getAvatar();
            //获取头像
            if (pictureMap.get(avatar) != null && pictureMap.get(avatar) != "") {
                user.setPhotoUrl(pictureMap.get(avatar));
            }

            rankMember.setUser(user);
        }

        //获取图片
        if (StringUtils.isNotEmpty(fileUid)) {
            List<String> pictureUidsTemp = StringUtils.changeStringToString(fileUid, SysConf.FILE_SEGMENTATION);
            List<String> pictureListTemp = new ArrayList<>();

            pictureUidsTemp.forEach(picture -> {
                pictureListTemp.add(pictureMap.get(picture));
            });
            // 只设置一张标题图
            if (pictureListTemp.size() > 0) {
                rankMember.setPhotoUrl(pictureListTemp.get(0));
            } else {
                rankMember.setPhotoUrl("");
            }
        }


        return rankMember;
    }

    /**
     * 给博客设置分类和用户信息
     *
     * @param rankMemberList
     * @return
     */
    @Override
    public List<RankMemberEntity> setRankMemberInfoWithPhotoUrl(List<RankMemberEntity> rankMemberList) {

        List<String> fileUidList = rankMemberList.stream().filter(e -> StringUtils.isNotEmpty(e.getFileUid())).map(RankMemberEntity::getFileUid).collect(Collectors.toList());

        if(ListUtils.isEmpty(fileUidList)) {
            return rankMemberList;
        }
        // 调用didiok-file接口查询图片
        Map<String, String> pictureMap = fileFeignUtil.fileUidToFileUrlMap(fileUidList);

        //获取图片
        for (RankMemberEntity rankMember : rankMemberList) {
            String fileUid = rankMember.getFileUid();
            if(StringUtils.isEmpty(fileUid)){
                continue;
            }
            List<String> pictureUidsTemp = StringUtils.changeStringToString(fileUid, SysConf.FILE_SEGMENTATION);
            List<String> pictureListTemp = new ArrayList<>();

            pictureUidsTemp.forEach(picture -> {
                pictureListTemp.add(pictureMap.get(picture));
            });
            // 只设置一张标题图
            if (pictureListTemp.size() > 0) {
                rankMember.setPhotoUrl(pictureListTemp.get(0));
            } else {
                rankMember.setPhotoUrl("");
            }
        }


        return rankMemberList;
    }

    // 过滤用户敏感信息
    private UserDto convertUser(UserDto item) {
        UserDto user = new UserDto();
        user.setUid(item.getUid());
        user.setAvatar(item.getAvatar());
        user.setPhotoUrl(item.getPhotoUrl());
        user.setNickname(item.getNickname());
        user.setOccupation(item.getOccupation());
        user.setSummary(item.getSummary());
        user.setCreateTime(item.getCreateTime());
        user.setLoadingValid(item.getLoadingValid());
        user.setStatus(item.getStatus());
        user.setGender(item.getGender());
        user.setUserTag(item.getUserTag());
        user.setCredits(item.getCredits());
        user.setExpValue(item.getExpValue());
        user.setUserLevel(UserLevelEnum.getLvByExpValue(item.getExpValue()).getLevel());
        user.setBackgroundFileUrl(item.getBackgroundFileUrl());
        user.setBackgroundFileUid(item.getBackgroundFileUid());

        // 过滤用户
        String ip = item.getLastLoginIp();
        String ipPossession = redisUtil.get(RedisConf.USER_IP_POSSESSION + Constants.SYMBOL_COLON + user.getUid());
        if (StringUtils.isEmpty(ipPossession) && StringUtils.isNotEmpty(ip)) {
            // ip属地
            ipPossession = IpUtils.getIpPossession(ip);
            // 将信息设置到redis中
            redisUtil.setEx(RedisConf.USER_IP_POSSESSION + Constants.SYMBOL_COLON + user.getUid(), ipPossession, 1, TimeUnit.HOURS);
        }
        user.setUserIpPossession(ipPossession);
        return user;
    }

    @Override
    public void checkVisitAuth(RankMemberEntity rankMember) {
        // 如果是公开可见，那么直接跳过
        if (VisitAuthTypeEnum.PUBLIC.getType().equals(rankMember.getVisitAuth())) {
            rankMember.setVisitAuthSuccess(true);
            return;
        }

        // 如果是输入验证后可见，需要判断Cookie中是否携带了校验code
        String userUid = RequestHolder.getUserUid();
        if (VisitAuthTypeEnum.CODE.getType().equals(rankMember.getVisitAuth())) {
            HttpServletRequest request = RequestHolder.getRequest();
            assert request != null;
            String validCode = request.getHeader("validCode");
//            String validCode = CookieUtils.getCookieValue(Objects.requireNonNull(RequestHolder.getRequest()), "validCode", false);
            // cookie中携带了验证码，校验通过
            if (StringUtils.isNotEmpty(validCode)) {
                checkOrSetAuth(rankMember, true);
                return;
            }
            // 用户没登录，直接退出登录
            if (StringUtils.isEmpty(userUid)) {
                checkOrSetAuth(rankMember, false);
                return;
            }
            R result = userFeignClient.getUserById(userUid);
            UserDto user = null;
            if (result.getCode() == 0) {
                user = result.getData(new TypeReference<UserDto>(){});
            }else {
                throw new FeignException("feign调用异常（根据用户id找用户）：失败");
            }
            checkOrSetAuth(rankMember, user != null && user.getLoadingValid() == 1);
            return;
        }

        // 判断是否是登录后可见，需要校验用户是否登录【如果没登录，后面的校验都通过不了，直接返回】
        if (!StringUtils.isNotEmpty(userUid)) {
            checkOrSetAuth(rankMember, false);
            return;
        }
        // 登录后可见
        if (VisitAuthTypeEnum.LOGIN.getType().equals(rankMember.getVisitAuth())) {
            // 能到这里肯定是已登录了，直接跳过
            checkOrSetAuth(rankMember, true);
            return;
        }
        // 能到这里肯定是已登录了，直接跳过
        checkOrSetAuth(rankMember, true);
        return;

    }

    @Override
    public Integer getRankMemberPraiseCountByUid(String uid) {
        Integer pariseCount = 0;
        if (StringUtils.isEmpty(uid)) {
            log.error("传入的UID为空");
            return pariseCount;
        }
        //从Redis取出用户点赞数据
        String pariseJsonResult = redisUtil.get(RedisConf.RANK_MEMBER_PRAISE + RedisConf.SEGMENTATION + uid);
        if (!StringUtils.isEmpty(pariseJsonResult)) {
            pariseCount = Integer.parseInt(pariseJsonResult);
        }
        return pariseCount;
    }

    @Override
    public IPage<RankMemberEntity> getSameRankMemberByGradeUid(String gradeUid) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(1);
        page.setSize(10);
        queryWrapper.like(SQLConf.GRADE_UID, gradeUid);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        IPage<RankMemberEntity> pageList = this.page(page, queryWrapper);
        List<RankMemberEntity> list = pageList.getRecords();
        list = this.setGradeAndRankByRankMemberList(list);
        pageList.setRecords(list);
        return pageList;
    }

    @Override
    public List<RankMemberEntity> getSameRankMemberByRankMemberUid(String rankMemberUid, String rankUid) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(1);
        page.setSize(10);
        // 通过分类来获取相关博客
        queryWrapper.eq(SQLConf.RANK_UID, rankUid);
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        IPage<RankMemberEntity> pageList = this.page(page, queryWrapper);
        List<RankMemberEntity> list = pageList.getRecords();
//        list = this.setGradeAndRankByRankMemberList(list);

        //过滤掉当前的博客
        List<RankMemberEntity> newList = new ArrayList<>();
        for (RankMemberEntity item : list) {
            if (item.getUid().equals(rankMemberUid)) {
                continue;
            }
            newList.add(item);
        }
        return newList;
    }

    /**
     * 通过 rankUid 获取榜单列表
     *
     * @param rankUid
     * @param currentPage
     * @param pageSize
     * @return
     */
    @Override
    public IPage<RankMemberEntity> getListByRankUid(String rankUid, Long currentPage, Long pageSize) {
        //分页
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(currentPage);
        page.setSize(pageSize);
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        queryWrapper.eq(BaseSQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(SQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(SQLConf.RANK_UID, rankUid);

        //因为首页并不需要显示内容，所以需要排除掉内容字段
        queryWrapper.select(RankMemberEntity.class, i -> !i.getProperty().equals(SQLConf.CONTENT));
        IPage<RankMemberEntity> pageList = this.page(page, queryWrapper);

        //给博客增加标签和分类
        List<RankMemberEntity> list = this.setGradeAndRankAndPictureByRankMemberList(pageList.getRecords());
        pageList.setRecords(list);
        return pageList;
    }

    @Override
    public Map<String, Object> getRankMemberByKeyword(String keywords, Long currentPage, Long pageSize) {
        final String keyword = keywords.trim();
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.and(wrapper -> wrapper.like(SQLConf.TITLE, keyword).or().like(SQLConf.SUMMARY, keyword).or().like(SQLConf.CREATE_USER_NAME, keyword));
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.select(RankMemberEntity.class, i -> !i.getProperty().equals(SQLConf.CONTENT));
        queryWrapper.orderByDesc(SQLConf.CLICK_COUNT);
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(currentPage);
        page.setSize(pageSize);

        IPage<RankMemberEntity> iPage = this.page(page, queryWrapper);
        List<RankMemberEntity> rankMemberList = iPage.getRecords();
        List<String> rankUidList = new ArrayList<>();
        List<String> fileUidList = new ArrayList<>();
        rankMemberList.forEach(item -> {
            // 获取图片uid
            rankUidList.add(item.getRankUid());
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                fileUidList.add(item.getFileUid());
            }
            // 给标题和简介设置高亮
            item.setMemberName(StringUtils.getHitCode(item.getMemberName(), keyword));
            item.setSummary(StringUtils.getHitCode(item.getSummary(), keyword));
            item.setCreateUserName(StringUtils.getHitCode(item.getCreateUserName(), keyword));
        });

        Map<String, String> pictureMap = fileFeignUtil.fileUidToFileUrlMap(fileUidList);

        Collection<RankEntity> rankList = new ArrayList<>();
        if (rankUidList.size() > 0) {
            rankList = rankService.listByIds(rankUidList);
        }

        Map<String, String> rankMap = new HashMap<>();
        rankList.forEach(item -> {
            rankMap.put(item.getUid(), item.getRankName());
        });

        // 设置榜单名 和 图片
        rankMemberList.forEach(item -> {
            if (rankMap.get(item.getRankUid()) != null) {
                item.setCatName(rankMap.get(item.getRankUid()));
            }

            //获取图片
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                List<String> pictureUidsTemp = StringUtils.changeStringToString(item.getFileUid(), SysConf.FILE_SEGMENTATION);
                List<String> pictureListTemp = new ArrayList<>();

                pictureUidsTemp.forEach(picture -> {
                    pictureListTemp.add(pictureMap.get(picture));
                });
                // 只设置一张标题图
                if (pictureListTemp.size() > 0) {
                    item.setPhotoUrl(pictureListTemp.get(0));
                } else {
                    item.setPhotoUrl("");
                }
            }
        });

        Map<String, Object> map = new HashMap<>();
        // 返回总记录数
        map.put(SysConf.TOTAL, iPage.getTotal());
        // 返回总页数
        map.put(SysConf.TOTAL_PAGE, iPage.getPages());
        // 返回当前页大小
        map.put(SysConf.PAGE_SIZE, pageSize);
        // 返回当前页
        map.put(SysConf.CURRENT_PAGE, iPage.getCurrent());
        // 返回数据
        map.put(SysConf.RANK_MEMBER_LIST, rankMemberList);
        return map;
    }

    @Override
    public IPage<RankMemberEntity> searchRankMemberByRank(String rankUid, Long currentPage, Long pageSize) {
        RankEntity rank = rankService.getById(rankUid);
        if (rank != null) {
            HttpServletRequest request = RequestHolder.getRequest();
            String ip = IpUtils.getIpAddr(request);

            //从Redis取出数据，判断该用户24小时内，是否点击过该分类
            String jsonResult = redisUtil.get(RedisConf.RANK_CLICK + RedisConf.SEGMENTATION + ip + RedisConf.WELL_NUMBER + rankUid);
            if (StringUtils.isEmpty(jsonResult)) {
                //给标签点击数增加
                int clickCount = rank.getClickCount() + 1;
                rank.setClickCount(clickCount);
                rank.updateById();
                //将该用户点击记录存储到redis中, 24小时后过期
                redisUtil.setEx(RedisConf.RANK_CLICK + RedisConf.SEGMENTATION + ip + RedisConf.WELL_NUMBER + rankUid, clickCount + "",
                        24, TimeUnit.HOURS);
            }
        }

        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(currentPage);
        page.setSize(pageSize);
        queryWrapper.eq(SQLConf.RANK_UID, rankUid);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(BaseSQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.STATUS, StatusEnum.ENABLE);
        // 排除博客详情
        queryWrapper.select(RankMemberEntity.class, i -> !i.getProperty().equals(SysConf.CONTENT));
        IPage<RankMemberEntity> pageList = this.page(page, queryWrapper);
        List<RankMemberEntity> list = pageList.getRecords();
        list = this.setRankAndGradeAndPictureByRankMemberList(list);
        pageList.setRecords(list);
        return pageList;
    }

    @Override
    public IPage<RankMemberEntity> searchRankMemberByUserName(String author, Long currentPage, Long pageSize) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(currentPage);
        page.setSize(pageSize);
        queryWrapper.eq(SQLConf.CREATE_USER_NAME, author);
        queryWrapper.eq(BaseSQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(BaseSQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        queryWrapper.select(RankMemberEntity.class, i -> !i.getProperty().equals(SysConf.CONTENT));
        IPage<RankMemberEntity> pageList = this.page(page, queryWrapper);
        List<RankMemberEntity> list = pageList.getRecords();
        list = this.setRankAndGradeAndPictureByRankMemberList(list);
        pageList.setRecords(list);
        return pageList;
    }

    /**
     * 根据id获取榜单成员
     *
     * @param uid
     * @return
     */
    @Override
    public RankMemberEntity getRankMemberById(String uid) {
        return this.getOne(
                new LambdaQueryWrapper<RankMemberEntity>()
                        .eq(RankMemberEntity::getUid, uid)
                        .eq(RankMemberEntity::getStatus, StatusEnum.ENABLE)
        );
    }

    /**
     * 榜单成员下架操作
     *
     * @param
     * @return
     */
    @Override
    public Boolean revocationRankMember(String uid) {
        return rankMemberDao.revocationRankMember(uid, "因举报过多暂时下架", AuditStatusEnum.REJECT, PublishEnum.NO_PUBLISH);

    }

    /**
     * 获取发表的文章数
     *
     * @param adminUid
     * @param userUid
     * @return
     */
    @Override
    public Integer getRankMemberCountByAdminOrUser(String adminUid, String userUid) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(adminUid)) {
            queryWrapper.eq(SQLConf.ADMINUID, adminUid);
        }
        if (StringUtils.isNotEmpty(userUid)) {
            queryWrapper.eq(SQLConf.CREATE_USER_UID, userUid);
        }
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        Integer blogCount = this.count(queryWrapper);
        return blogCount;
    }

    @Override
    public Integer getRankMemberCount(RankMemberDto rankMemberDto) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(rankMemberDto.getAdminUid())) {
            queryWrapper.eq(SQLConf.ADMINUID, rankMemberDto.getAdminUid());
        }
        if (StringUtils.isNotEmpty(rankMemberDto.getCreateUserUid())) {
            queryWrapper.eq(SQLConf.USER_UID, rankMemberDto.getCreateUserUid());
        }
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        Integer rankMemberCount = this.count(queryWrapper);
        return rankMemberCount;
    }

    // endregion
    /***************************** didiok-web:end **************************/


    /**
     * 保存并发布榜单成员
     *
     * @param vo
     */
    @Transactional
    @Override
    public void saveAndPublish(RankMemberSaveVo vo) {

        //1、保存榜单成员的基本信息
        RankMemberEntity rankMemberEntity = new RankMemberEntity();
        if (rankMemberEntity.getGradeUid() == null) {
            rankMemberEntity.setGradeUid("1");
        }
        BeanUtils.copyProperties(vo, rankMemberEntity);
        baseMapper.insert(rankMemberEntity);

        //2、保存榜单成员的详情内容
        String content = vo.getContent();
        MemberContentEntity contentEntity = new MemberContentEntity();
        contentEntity.setMemberUid(rankMemberEntity.getUid());
        contentEntity.setContent(content);
        memberContentService.save(contentEntity);

        // 3、保存榜单成员的投票数
        VoteCountEntity voteCountEntity = new VoteCountEntity();
        voteCountEntity.setMemberUid(rankMemberEntity.getUid());
        voteCountEntity.setClickCount(0);
        voteCountEntity.setOpposeCount(0);
        voteCountEntity.setRecentVoteCount(0);
        voteCountEntity.setVoteCount(0);
        voteCountDao.insert(voteCountEntity);

        //4、保存榜单成员的属性
        List<Attrs> attrsList = vo.getAttrs();
        List<AttrValueEntity> collect = attrsList.stream().map(attr -> {
            AttrValueEntity valueEntity = new AttrValueEntity();
            valueEntity.setAttrUid(attr.getUid());
            // TODO 优化成批量查询
            AttrEntity id = attrService.getById(attr.getUid());
            valueEntity.setAttrName(id.getAttrName());
            valueEntity.setAttrValue(attr.getAttrValue());
            valueEntity.setMemberUid(rankMemberEntity.getUid());

            return valueEntity;
        }).collect(Collectors.toList());
        attrValueService.saveRankMemberAttr(collect);

        Integer isPublish = vo.getIsPublish();
        if (RankMemberPublishStatusEnum.PUBLISHED.equals(isPublish)) {
            // TODO 优化一下其中的重复查询，有的可以不用查询，直接复用入参数据
            // 榜单成员发布
            memberPublish(rankMemberEntity.getUid());
        }
    }


    /**
     * 榜单成员发布
     *
     * @param memberUid
     */
    @Override
    public void memberPublish(String memberUid) {

        //1、根据 memberId 获取 member 信息
        RankMemberEntity memberEntity = baseMapper.selectById(memberUid);
        //组装需要的数据
        RankMemberEsModel esModel = new RankMemberEsModel();

        //TODO  可以做成联表查询
        // 2、查询当前memberId对应的的所有可以被用来检索的规格属性，
        List<AttrValueEntity> attrValues = attrValueService.listAttrByMemeberId(memberUid);
        if (!ListUtils.isEmpty(attrValues)) {
            List<String> attrIds = attrValues.stream().map(attr -> {
                return attr.getAttrUid();
            }).collect(Collectors.toList());

            List<String> searchAttrIds = attrService.selectSearchAttrIds(attrIds);

            Set<String> idSet = new HashSet<>(searchAttrIds);

            List<RankMemberEsModel.Attrs> attrsList = attrValues.stream().filter(item -> {
                return idSet.contains(item.getAttrUid());
            }).map(item -> {
                RankMemberEsModel.Attrs attrs = new RankMemberEsModel.Attrs();
                BeanUtils.copyProperties(item, attrs);
                return attrs;
            }).collect(Collectors.toList());

            //设置检索属性
            esModel.setAttrs(attrsList);
        }
        //3、封装榜单成员的信息
        BeanUtils.copyProperties(memberEntity, esModel);

        //4、hotScore 热度评分。0
        esModel.setHotScore(0);

        //5、查询榜单和分类的名字信息
        if (null != esModel.getRankId()) {
            RankEntity rankEntity = rankService.getById(esModel.getRankId());
            if (null != rankEntity) {
                esModel.setRankName(rankEntity.getRankName());
                esModel.setRankLogo(rankEntity.getLogo());
            }
        }

        if (null != esModel.getCatId()) {
            RankCategoryEntity category = rankCategoryService.getById(esModel.getCatId());
            if (null != category) {
                esModel.setCatName(category.getCatName());
            }
        }

        // 6、查询等级信息
        if (memberEntity.getGradeUid() != null) {
            MemberGradeEntity gradeEntity = memberGradeDao.selectGradeNameByGradeId(memberEntity.getGradeUid());
            if (gradeEntity != null) {
                esModel.setGradeName(gradeEntity.getGradeName());
            }
        }

        // 7、查询投票数和反对数
        VoteCountEntity countEntity = voteCountDao.selectByMemberUid(memberUid);
        if (countEntity != null) {
            esModel.setVoteCount(countEntity.getVoteCount());
            esModel.setOpposeCount(countEntity.getOpposeCount());
        }

        //8、将数据发送给es进行保存；didiok-search；
        R r = searchFeignClient.rankMemberPublish(Collections.singletonList(esModel));
        if (r.getCode() == 0) {
            //远程调用成功
            //8、修改当前榜单成员的状态
            baseMapper.updateRankMemberPublishStatus(memberUid, RankMemberPublishStatusEnum.PUBLISHED.getCode());
        } else {
            //远程调用失败
            //10、重复调用？接口幂等性；重试机制？xxx

        }

    }

    /**
     * 根据条件查询榜单成员列表
     *
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPageByCondition(Map<String, Object> params) {

        QueryWrapper<RankMemberEntity> wrapper = new QueryWrapper<>();

        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            wrapper.and((w) -> {
                w.eq("member_id", key).or().like("member_name", key);
            });
        }
        // is_publish=1 and (member_id=1 or member_name like xxx)
        String isPublish = (String) params.get("isPublish");
        if (!StringUtils.isEmpty(isPublish)) {
            wrapper.eq("is_publish", isPublish);
        }

        String rankId = (String) params.get("rankId");
        if (!StringUtils.isEmpty(rankId) && !"0".equalsIgnoreCase(rankId)) {
            wrapper.eq("rank_id", rankId);
        }

        String catId = (String) params.get("catId");
        if (!StringUtils.isEmpty(catId) && !"0".equalsIgnoreCase(catId)) {
            wrapper.eq("cat_id", catId);
        }

        /**
         * isPublish: 1
         * key:
         * rankId: 9
         * catId: 225
         */

        IPage<RankMemberEntity> page = this.page(
                new Query<RankMemberEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    /**
     * 查询当前榜单成员的详情
     *
     * @param memberUid
     * @return
     */
    @Override
    public RankMemberDetailVo detail(String memberUid) throws ExecutionException, InterruptedException {
        RankMemberDetailVo memberDetailVo = new RankMemberDetailVo();

        // TODO (只是标记一下，不需要todo)获取主线程的请求域
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        CompletableFuture<RankMemberEntity> memberFuture = CompletableFuture.supplyAsync(() -> {
            // TODO (只是标记一下，不需要todo)将主线程的请求域放在该线程的请求域中
            RequestContextHolder.setRequestAttributes(requestAttributes);

            //1、榜单成员基本信息获取
            RankMemberEntity memberEntity = getById(memberUid);
            memberDetailVo.setRankMember(memberEntity);
            return memberEntity;
        }, threadPoolExecutor);

        CompletableFuture<Void> contentFuture = memberFuture.thenAcceptAsync(res -> {
            // TODO (只是标记一下，不需要todo)将主线程的请求域放在该线程的请求域中
            RequestContextHolder.setRequestAttributes(requestAttributes);

            //2、获取榜单成员的详情内容
            MemberContentEntity contentEntity = memberContentService.getById(res.getUid());
            memberDetailVo.setContent(contentEntity);
        }, threadPoolExecutor);

        CompletableFuture<Void> countFuture = memberFuture.thenAcceptAsync(res -> {
            // TODO (只是标记一下，不需要todo)将主线程的请求域放在该线程的请求域中
            RequestContextHolder.setRequestAttributes(requestAttributes);

            //3、获取榜单成员的投票数
            VoteCountEntity countEntity = voteCountService.getById(res.getUid());
            memberDetailVo.setVoteCount(countEntity);
        }, threadPoolExecutor);

        CompletableFuture<Void> attrFuture = memberFuture.thenAcceptAsync(res -> {
            //4、获取榜单成员的属性信息。
            List<RankMemberAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsByMemberId(res.getUid(), res.getCatUid());
            memberDetailVo.setGroupAttrs(attrGroupVos);
        }, threadPoolExecutor);

        //等到所有任务都完成(memberFuture执行完成后才会执行其它异步操作，所以下面allOf()中便不写memberFuture了)
        CompletableFuture.allOf(countFuture, contentFuture, attrFuture).get();

        return memberDetailVo;
    }



    @Override
    public Integer getRankMemberPublishCount(String userUid) {
        if (StringUtils.isEmpty(userUid)) {
            return 0;
        }
        String rankMemberVisitCountJson = redisUtil.get(RedisConf.RANK_MEMBER_PUBLISH_COUNT + Constants.SYMBOL_COLON + userUid);
        if (StringUtils.isNotEmpty(rankMemberVisitCountJson)) {
            return Integer.valueOf(rankMemberVisitCountJson);
        }
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.CREATE_USER_UID, userUid);
        queryWrapper.eq(SQLConf.RANK_MEMBER_SOURCE, ContributeSourceEnum.USER_PUBLISH);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(SQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        Integer rankMemberPublishCount = this.count(queryWrapper);
        redisUtil.setEx(RedisConf.RANK_MEMBER_PUBLISH_COUNT + Constants.SYMBOL_COLON + userUid, JsonUtils.objectToJson(rankMemberPublishCount), 10, TimeUnit.MINUTES);
        return rankMemberPublishCount;
    }

    @Override
    public Integer getRankMemberVisitCount(String userUid) {
        Integer rankMemberVisitCount = 0;
        if (StringUtils.isEmpty(userUid)) {
            return rankMemberVisitCount;
        }

        String rankMemberVisitCountJson = redisUtil.get(RedisConf.RANK_MEMBER_VISIT_COUNT + Constants.SYMBOL_COLON + userUid);
        if (StringUtils.isNotEmpty(rankMemberVisitCountJson)) {
            return Integer.valueOf(rankMemberVisitCountJson);
        }

        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.USER_UID, userUid);
        queryWrapper.eq(SQLConf.ARTICLE_SOURCE, ContributeSourceEnum.USER_PUBLISH);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        // 只获取uid信息
        queryWrapper.select(SQLConf.OID, SQLConf.UID);
        List<RankMemberEntity> rankMemberList = this.list(queryWrapper);
        List<String> visitUidList = new ArrayList<>();
        rankMemberList.forEach(item -> {
            visitUidList.add(item.getUid());
        });

        if (visitUidList.size() > 0) {
            QueryWrapper<MemberVisitEntity> webVisitQueryWrapper = new QueryWrapper<>();
            // 兼容历史数据
            webVisitQueryWrapper.in(SQLConf.MODULE_UID, visitUidList);
            rankMemberVisitCount = memberVisitService.count(webVisitQueryWrapper);
            redisUtil.setEx(RedisConf.RANK_MEMBER_VISIT_COUNT + Constants.SYMBOL_COLON + userUid, JsonUtils.objectToJson(rankMemberVisitCount), 10, TimeUnit.MINUTES);
        }
        return rankMemberVisitCount;
    }

    @Override
    public List<RankMemberEntity> convertRankMemberInfoList(List<RankMemberEntity> list) {
        if (list.size() == 0) {
            return new ArrayList<>();
        }
        return this.setRankMemberWithUser(list);
    }

    /**
     * 设置博客的分类标签和内容
     *
     * @param list
     * @return
     */
    private List<RankMemberEntity> setRankMemberWithUser(List<RankMemberEntity> list) {
        List<String> fileUidList = new ArrayList<>();
        List<String> rankUids = new ArrayList<>();
        List<String> gradeUids = new ArrayList<>();
        Set<String> userUidList = new HashSet<>();
        Set<String> adminUidList = new HashSet<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                fileUidList.add(item.getFileUid());
            }
            if (StringUtils.isNotEmpty(item.getRankUid())) {
                rankUids.add(item.getRankUid());
            }
            if (StringUtils.isNotEmpty(item.getGradeUid())) {
                gradeUids.add(item.getGradeUid());
            }

            // 判断用户投稿，还是后台管理员添加
            if (ContributeSourceEnum.USER_PUBLISH.equals(item.getRankMemberSource())) {
                if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                    userUidList.add(item.getCreateUserUid());
                }
            } else {
                if (StringUtils.isNotEmpty(item.getAdminUid())) {
                    adminUidList.add(item.getAdminUid());
                }
            }
        });
        Collection<RankEntity> rankList = new ArrayList<>();
        Collection<MemberGradeEntity> gradeList = new ArrayList<>();
        if (rankUids.size() > 0) {
            rankList = rankService.listByIds(rankUids);
        }
        if (gradeUids.size() > 0) {
            gradeList = memberGradeService.listByIds(gradeUids);
        }

        Map<String, RankEntity> rankMap = rankList.stream().collect(Collectors.toMap(RankEntity::getUid, v->v, (v1,v2)->v2));
        Map<String, MemberGradeEntity> gradeMap = gradeList.stream().collect(Collectors.toMap(MemberGradeEntity::getUid, v->v, (v1,v2)->v2));



        // 获取用户信息
        List<UserDto> userList = new ArrayList<>();
        if (userUidList.size() > 0) {
            R result = userFeignClient.getUserListWithoutAvatarByIds(userUidList);
            if(result.getCode() == 0){
                userList = result.getData(new TypeReference<List<UserDto>>(){});
            }else {
                throw new FeignException("feign调用异常（通过ids获取用户列表【携带用户头像和背景图片】）：失败");
            }

        }
        List<AdminDto> adminList = new ArrayList<>();
        if (adminUidList.size() > 0) {
            R result = adminFeignClient.getAdminListWithoutPhotoByUid(adminUidList);
            if (result.getCode() == 0) {
                adminList = result.getData(new TypeReference<List<AdminDto>>(){});
            }
        }

        userList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getAvatar())) {
                fileUidList.add(item.getAvatar());
            }
            if (StringUtils.isNotEmpty(item.getBackgroundFileUid())) {
                fileUidList.add(item.getBackgroundFileUid());
            }
        });
        adminList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getAvatar())) {
                fileUidList.add(item.getAvatar());
            }
        });

        Map<String, String> pictureMap = fileFeignUtil.fileUidToFileUrlMap(fileUidList);

        Map<String, UserDto> userMap = userList.stream().collect(Collectors.toMap(UserDto::getUid, v->v,(v1,v2)->v2));
        Map<String, AdminDto> adminMap = adminList.stream().collect(Collectors.toMap(AdminDto::getUid, v->v,(v1,v2)->v2));


        for (RankMemberEntity item : list) {

            //设置分类
            if (StringUtils.isNotEmpty(item.getRankUid())) {
                item.setRank(rankMap.get(item.getRankUid()));
            }

            //获取标签
            if (StringUtils.isNotEmpty(item.getGradeUid())) {
                item.setGrade(gradeMap.get(item.getGradeUid()));
            }

            //获取图片
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                List<String> pictureUidsTemp = StringUtils.changeStringToString(item.getFileUid(), SysConf.FILE_SEGMENTATION);
                List<String> pictureListTemp = new ArrayList<>();

                pictureUidsTemp.forEach(picture -> {
                    pictureListTemp.add(pictureMap.get(picture));
                });
                item.setPhotoList(pictureListTemp);
            }

            //获取用户【判断是用户投稿，还是后台添加】
            if (ContributeSourceEnum.USER_PUBLISH.equals(item.getRankMemberSource())) {
                if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                    item.setUser(userMap.get(item.getCreateUserUid()));
                }
            } else {
                if (StringUtils.isNotEmpty(item.getAdminUid())) {
                    UserDto user = new UserDto();
                    AdminDto admin = adminMap.get(item.getAdminUid());
                    if (admin != null) {
                        user.setAvatar(admin.getAvatar());
                        user.setUid(admin.getUid());
                        user.setOccupation(admin.getOccupation());
                        user.setGender(admin.getGender());
                        user.setSummary(admin.getSummary());
                        user.setNickname(admin.getNickname());
                        String avatar = admin.getAvatar();
                        if (StringUtils.isNotEmpty(avatar)) {
                            if (pictureMap.get(avatar) != null && pictureMap.get(avatar) != "") {
                                user.setPhotoUrl(pictureMap.get(avatar));
                            }
                        }

                    }else {
                        //获取头像
                        if (StringUtils.isNotEmpty(user.getAvatar())) {
                            List<String> pictureUidsTemp = StringUtils.changeStringToString(user.getAvatar(), SysConf.FILE_SEGMENTATION);
                            List<String> pictureListTemp = new ArrayList<>();
                            pictureUidsTemp.forEach(picture -> {
                                if (pictureMap.get(picture) != null && pictureMap.get(picture) != "") {
                                    pictureListTemp.add(pictureMap.get(picture));
                                }
                            });
                            if (pictureListTemp.size() > 0) {
                                user.setPhotoUrl(pictureListTemp.get(0));
                            }
                        }

                        //获取图片
                        if (StringUtils.isNotEmpty(user.getBackgroundFileUid())) {
                            user.setBackgroundFileUrl(pictureMap.get(user.getBackgroundFileUid()));
                        }
                    }
                    item.setUser(user);
                }
            }
        }
        return list;
    }

    @Override
    public List<RankMemberEntity> setTagAndRankByRankMemberList(List<RankMemberEntity> list) {
        List<String> rankUids = new ArrayList<>();
        List<String> tagUids = new ArrayList<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getRankUid())) {
                rankUids.add(item.getRankUid());
            }
            if (StringUtils.isNotEmpty(item.getTagUid())) {
                List<String> tagUidsTemp = StringUtils.changeStringToString(item.getTagUid(), BaseSysConf.FILE_SEGMENTATION);
                for (String itemTagUid : tagUidsTemp) {
                    tagUids.add(itemTagUid);
                }
            }
        });
        Collection<RankEntity> rankList = new ArrayList<>();
        Collection<MemberTagEntity> tagList = new ArrayList<>();
        if (rankUids.size() > 0) {
            rankList = rankDao.selectBatchIds(rankUids);
        }
        if (tagUids.size() > 0) {
            tagList = memberTagDao.selectBatchIds(tagUids);
        }
        Map<String, RankEntity> rankMap = new HashMap<>();
        Map<String, MemberTagEntity> tagMap = new HashMap<>();
        rankList.forEach(item -> {
            rankMap.put(item.getUid(), item);
        });
        tagList.forEach(item -> {
            tagMap.put(item.getUid(), item);
        });
        for (RankMemberEntity item : list) {

            //设置分类
            if (StringUtils.isNotEmpty(item.getRankUid())) {
                item.setRank(rankMap.get(item.getRankUid()));
            }
            //获取标签
            if (StringUtils.isNotEmpty(item.getTagUid())) {
                List<String> tagUidsTemp = StringUtils.changeStringToString(item.getTagUid(), BaseSysConf.FILE_SEGMENTATION);
                List<MemberTagEntity> tagListTemp = new ArrayList<MemberTagEntity>();
                tagUidsTemp.forEach(tag -> {
                    tagListTemp.add(tagMap.get(tag));
                });
                item.setTagList(tagListTemp);
            }
        }

        return list;
    }

    @Override
    public List<RankMemberEntity> setGradeAndRankByRankMemberList(List<RankMemberEntity> list) {
        List<String> rankUids = new ArrayList<>();
        List<String> memberGradeUids = new ArrayList<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getRankUid())) {
                rankUids.add(item.getRankUid());
            }
            if (StringUtils.isNotEmpty(item.getGradeUid())) {
                memberGradeUids.add(item.getGradeUid());
            }
        });
        Collection<RankEntity> rankList = new ArrayList<>();
        Collection<MemberGradeEntity> memberGradeList = new ArrayList<>();
        if (rankUids.size() > 0) {
            rankList = rankDao.selectBatchIds(rankUids);
        }
        if (memberGradeUids.size() > 0) {
            memberGradeList = memberGradeDao.selectBatchIds(memberGradeUids);
        }
        Map<String, RankEntity> rankMap = new HashMap<>();
        Map<String, MemberGradeEntity> memberGradeMap = new HashMap<>();
        rankList.forEach(item -> {
            rankMap.put(item.getUid(), item);
        });
        memberGradeList.forEach(item -> {
            memberGradeMap.put(item.getUid(), item);
        });
        for (RankMemberEntity item : list) {

            //设置榜单
            if (StringUtils.isNotEmpty(item.getRankUid())) {
                item.setRank(rankMap.get(item.getRankUid()));
            }
            //获取标签
            if (StringUtils.isNotEmpty(item.getGradeUid())) {
                item.setGrade(memberGradeMap.get(item.getGradeUid()));
            }
        }

        return list;
    }

    @Override
    public List<RankMemberEntity> setGradeAndRankAndPictureByRankMemberList(List<RankMemberEntity> list) {

        List<String> rankUids = new ArrayList<>();
        List<String> memberGradeUids = new ArrayList<>();
        Set<String> fileUidSet = new HashSet<>();

        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                fileUidSet.add(item.getFileUid());
            }
            if (StringUtils.isNotEmpty(item.getRankUid())) {
                rankUids.add(item.getRankUid());
            }
            if (StringUtils.isNotEmpty(item.getGradeUid())) {
                memberGradeUids.add(item.getGradeUid());
            }
        });

        String pictureList = null;
        StringBuffer fileUids = new StringBuffer();
        List<Map<String, Object>> picList = new ArrayList<>();
        // feign分页查询图片数据
        if (fileUidSet.size() > 0) {
            int count = 1;
            for (String fileUid : fileUidSet) {
                fileUids.append(fileUid + ",");
                System.out.println(count % 10);
                if (count % 10 == 0) {
                    pictureList = this.fileFeignClient.getPicture(fileUids.toString(), ",");
                    List<Map<String, Object>> tempPicList = webUtil.getPictureMap(pictureList);
                    picList.addAll(tempPicList);
                    fileUids = new StringBuffer();
                }
                count++;
            }
            // 判断是否存在图片需要获取
            if (fileUids.length() >= Constants.NUM_32) {
                pictureList = this.fileFeignClient.getPicture(fileUids.toString(), Constants.SYMBOL_COMMA);
                List<Map<String, Object>> tempPicList = webUtil.getPictureMap(pictureList);
                picList.addAll(tempPicList);
            }
        }

        Collection<RankEntity> rankList = new ArrayList<>();
        Collection<MemberGradeEntity> gradeList = new ArrayList<>();
        if (rankUids.size() > 0) {
            rankList = rankService.listByIds(rankUids);
        }
        if (memberGradeUids.size() > 0) {
            gradeList = memberGradeService.listByIds(memberGradeUids);
        }
        Map<String, RankEntity> rankMap = new HashMap<>();
        Map<String, MemberGradeEntity> gradeMap = new HashMap<>();
        Map<String, String> pictureMap = new HashMap<>();

        rankList.forEach(item -> {
            rankMap.put(item.getUid(), item);
        });

        gradeList.forEach(item -> {
            gradeMap.put(item.getUid(), item);
        });

        picList.forEach(item -> {
            pictureMap.put(item.get(SysConf.UID).toString(), item.get(SysConf.URL).toString());
        });

        for (RankMemberEntity item : list) {
            //设置分类
            if (StringUtils.isNotEmpty(item.getRankUid())) {

                item.setRank(rankMap.get(item.getRankUid()));
                if (rankMap.get(item.getRankUid()) != null) {
                    item.setRankName(rankMap.get(item.getRankUid()).getRankName());
                }
            }

            //获取标签
            if (StringUtils.isNotEmpty(item.getGradeUid())) {

                item.setGrade(gradeMap.get(item.getGradeUid()));
            }

            //获取图片
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                List<String> pictureUidsTemp = StringUtils.changeStringToString(item.getFileUid(), Constants.SYMBOL_COMMA);
                List<String> pictureListTemp = new ArrayList<String>();

                pictureUidsTemp.forEach(picture -> {
                    pictureListTemp.add(pictureMap.get(picture));
                });
                item.setPhotoList(pictureListTemp);
                // 只设置一张标题图
                if (pictureListTemp.size() > 0) {
                    item.setPhotoUrl(pictureListTemp.get(0));
                } else {
                    item.setPhotoUrl("");
                }
            }
        }
        return list;
    }

    @Override
    public RankMemberEntity setMemberGradeByRankMember(RankMemberEntity rankMember) {
        String tagUid = rankMember.getTagUid();
        if (!StringUtils.isEmpty(tagUid)) {
            String[] uids = tagUid.split(SysConf.FILE_SEGMENTATION);
            List<MemberGradeEntity> memberGradeList = new ArrayList<>();
            for (String uid : uids) {
                MemberGradeEntity tag = memberGradeDao.selectById(uid);
                if (tag != null && tag.getStatus() != StatusEnum.DISABLED) {
                    memberGradeList.add(tag);
                }
            }
            rankMember.setGradeList(memberGradeList);
        }
        return rankMember;
    }

    @Override
    public RankMemberEntity setRankMemberInfo(RankMemberEntity rankMember) {
        List<RankMemberEntity> rankMemberList = new ArrayList<>();
        rankMemberList.add(rankMember);
        this.setRankMember(rankMemberList);
        return rankMemberList.get(0);
    }

    @Override
    public RankMemberEntity setCategoryByRankMember(RankMemberEntity rankMember) {

        if (rankMember != null && !StringUtils.isEmpty(rankMember.getCatUid())) {
            RankCategoryEntity rankCategoryEntity = rankCategoryDao.selectById(rankMember.getCatUid());
            rankMember.setCategory(rankCategoryEntity);
        }
        return rankMember;
    }

    @Override
    public List<RankMemberEntity> getRankMemberListByLevel(Integer level) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(BaseSQLConf.LEVEL, level);
        queryWrapper.eq(BaseSQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);

        List<RankMemberEntity> list = rankMemberDao.selectList(queryWrapper);
        return list;
    }

    @Override
    public IPage<RankMemberEntity> getRankMemberPageByLevel(Page<RankMemberEntity> page, Integer level, Integer useSort) {
        // TODO 编写自定义sql,过滤掉报名已结束的活动
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(BaseSQLConf.LEVEL, level);
        queryWrapper.eq(BaseSQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(BaseSQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);

        if (useSort == 0) {
            queryWrapper.orderByDesc(BaseSQLConf.CREATE_TIME);
        } else {
            queryWrapper.orderByDesc(BaseSQLConf.SORT);
        }

        //因为首页并不需要显示内容，所以需要排除掉内容字段
        queryWrapper.select(RankMemberEntity.class, i -> !i.getProperty().equals(SysConf.CONTENT));

        return rankMemberDao.selectPage(page, queryWrapper);
    }

    @Override
    public Integer getRankMemberCount(Integer status) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(BaseSQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(BaseSQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        return rankMemberDao.selectCount(queryWrapper);
    }

    @Override
    public List<Map<String, Object>> getRankMemberCountByMemberGrade() {
        // 从Redis中获取标签下包含的博客数量
        String jsonArrayList = redisUtil.get(RedisConf.DASHBOARD + Constants.SYMBOL_COLON + RedisConf.RANK_MEMBER_COUNT_BY_GRADE);
        if (StringUtils.isNotEmpty(jsonArrayList)) {
            ArrayList jsonList = JsonUtils.jsonArrayToArrayList(jsonArrayList);
            return jsonList;
        }

        List<Map<String, Object>> rankMemberCoutByTagMap = rankMemberDao.getRankMemberCountByMemberGrade();
        Map<String, Integer> tagMap = new HashMap<>();
        for (Map<String, Object> item : rankMemberCoutByTagMap) {
            String tagUid = String.valueOf(item.get(SQLConf.TAG_UID));
            // java.lang.Number是Integer,Long的父类
            Number num = (Number) item.get(SysConf.COUNT);
            Integer count = num.intValue();
            //如果只有一个UID的情况
            if (tagUid.length() == 32) {
                //如果没有这个内容的话，就设置
                if (tagMap.get(tagUid) == null) {
                    tagMap.put(tagUid, count);
                } else {
                    Integer tempCount = tagMap.get(tagUid) + count;
                    tagMap.put(tagUid, tempCount);
                }
            } else {
                //如果长度大于32，说明含有多个UID
                if (StringUtils.isNotEmpty(tagUid)) {
                    List<String> strList = StringUtils.changeStringToString(tagUid, ",");
                    for (String strItem : strList) {
                        if (tagMap.get(strItem) == null) {
                            tagMap.put(strItem, count);
                        } else {
                            Integer tempCount = tagMap.get(strItem) + count;
                            tagMap.put(strItem, tempCount);
                        }
                    }
                }
            }
        }

        //把查询到的Tag放到Map中
        Set<String> tagUids = tagMap.keySet();
        Collection<MemberGradeEntity> tagCollection = new ArrayList<>();
        if (tagUids.size() > 0) {
            tagCollection = memberGradeDao.selectBatchIds(tagUids);
        }

        Map<String, String> tagEntityMap = new HashMap<>();
        for (MemberGradeEntity gradeEntity : tagCollection) {
            if (StringUtils.isNotEmpty(gradeEntity.getGradeName())) {
                tagEntityMap.put(gradeEntity.getUid(), gradeEntity.getGradeName());
            }
        }

        List<Map<String, Object>> resultList = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : tagMap.entrySet()) {
            String tagUid = entry.getKey();
            if (tagEntityMap.get(tagUid) != null) {
                String tagName = tagEntityMap.get(tagUid);
                Integer count = entry.getValue();
                Map<String, Object> itemResultMap = new HashMap<>();
                itemResultMap.put(SysConf.TAG_UID, tagUid);
                itemResultMap.put(SysConf.NAME, tagName);
                itemResultMap.put(SysConf.VALUE, count);
                resultList.add(itemResultMap);
            }
        }
        // 将 每个标签下文章数目 存入到Redis【过期时间2小时】
        if (resultList.size() > 0) {
            redisUtil.setEx(RedisConf.DASHBOARD + Constants.SYMBOL_COLON + RedisConf.RANK_MEMBER_COUNT_BY_GRADE, JsonUtils.objectToJson(resultList), 2, TimeUnit.HOURS);
        }
        return resultList;
    }

    @Override
    public List<Map<String, Object>> getRankMemberCountByCategory() {
        // 从Redis中获取博客分类下包含的博客数量
        String jsonArrayList = redisUtil.get(RedisConf.DASHBOARD + Constants.SYMBOL_COLON + RedisConf.RANK_COUNT_BY_CATEGORY);
        if (StringUtils.isNotEmpty(jsonArrayList)) {
            ArrayList jsonList = JsonUtils.jsonArrayToArrayList(jsonArrayList);
            return jsonList;
        }
        List<Map<String, Object>> rankMemberCoutByCatMap = rankMemberDao.getRankMemberCountByCategory();
        Map<String, Integer> rankMemberSortMap = new HashMap<>();
        for (Map<String, Object> item : rankMemberCoutByCatMap) {

            String rankMemberSortUid = String.valueOf(item.get(SQLConf.CAT_UID));
            // java.lang.Number是Integer,Long的父类
            Number num = (Number) item.get(SysConf.COUNT);
            Integer count = 0;
            if (num != null) {
                count = num.intValue();
            }
            rankMemberSortMap.put(rankMemberSortUid, count);
        }

        //把查询到的Cat放到Map中
        Set<String> rankMemberSortUids = rankMemberSortMap.keySet();
        Collection<RankCategoryEntity> rankMemberSortCollection = new ArrayList<>();

        if (rankMemberSortUids.size() > 0) {
            rankMemberSortCollection = rankCategoryDao.selectBatchIds(rankMemberSortUids);
        }

        Map<String, String> rankMemberSortEntityMap = new HashMap<>();
        for (RankCategoryEntity rankCategoryEntity : rankMemberSortCollection) {
            if (StringUtils.isNotEmpty(rankCategoryEntity.getCatName())) {
                rankMemberSortEntityMap.put(rankCategoryEntity.getUid(), rankCategoryEntity.getCatName());
            }
        }

        List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
        for (Map.Entry<String, Integer> entry : rankMemberSortMap.entrySet()) {

            String rankMemberSortUid = entry.getKey();

            if (rankMemberSortEntityMap.get(rankMemberSortUid) != null) {
                String rankMemberSortName = rankMemberSortEntityMap.get(rankMemberSortUid);
                Integer count = entry.getValue();
                Map<String, Object> itemResultMap = new HashMap<>();
                itemResultMap.put(SysConf.CAT_UID, rankMemberSortUid);
                itemResultMap.put(SysConf.NAME, rankMemberSortName);
                itemResultMap.put(SysConf.VALUE, count);
                resultList.add(itemResultMap);
            }
        }
        // 将 每个分类下文章数目 存入到Redis【过期时间2小时】
        if (resultList.size() > 0) {
            redisUtil.setEx(RedisConf.DASHBOARD + Constants.SYMBOL_COLON + RedisConf.RANK_COUNT_BY_CATEGORY, JsonUtils.objectToJson(resultList), 2, TimeUnit.HOURS);
        }
        return resultList;
    }

    @Override
    public RankMemberEntity getRankMemberByUid(String uid) {
        RankMemberEntity rankMember = rankMemberDao.selectById(uid);
        if (rankMember != null && rankMember.getStatus() != StatusEnum.DISABLED) {
            rankMember = setMemberGradeByRankMember(rankMember);
            rankMember = setCategoryByRankMember(rankMember);
            return rankMember;
        }
        return null;
    }

    @Override
    public List<RankMemberEntity> getRankMemberListByTop(Integer top) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(1);
        page.setSize(top);
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.orderByDesc(SQLConf.SORT);
        IPage<RankMemberEntity> pageList = this.page(page, queryWrapper);
        List<RankMemberEntity> list = pageList.getRecords();
        list = this.setGradeAndRankAndPictureByRankMemberList(list);
        return list;
    }

    @Override
    public String batchAuditRankMember(List<String> uidList, String nickname, String auditStatus, String rejectReason) {
        if (uidList.size() <= 0) {
            return ResultUtil.errorWithMessage(MessageConf.PARAM_INCORRECT);
        }

        Collection<RankMemberEntity> rankMemberList = this.listByIds(uidList);

        String finalAuditStatus = auditStatus;
        String finalRejectReason = rejectReason;
        String finalNickname = nickname;
        rankMemberList.forEach(item -> {
            item.setAuditName(finalNickname);
            item.setAuditTime(new Date());
            if (AuditStatusEnum.AGREE.equals(item.getAuditStatus())) {
                throw new UpdateException("审批失败，存在已完成审批的博客");
            }
            if (AuditStatusEnum.AGREE.equals(finalAuditStatus)) {
                // 审批通过，自动上架
                item.setAuditStatus(AuditStatusEnum.AGREE);
                item.setIsPublish(PublishEnum.PUBLISH);
                // 增加用户积分
//                userFeignClient.addUserCredits(CreditTypeEnum.RankMember.getAction(), null, item.getUid(), item.getCreateUserUid());
            } else if (AuditStatusEnum.REJECT.equals(finalAuditStatus)) {
                // 审批通过，自动下架
                item.setIsPublish(PublishEnum.NO_PUBLISH);
                item.setAuditStatus(AuditStatusEnum.REJECT);
                item.setRejectReason(finalRejectReason);
            } else {
                throw new UpdateException("审批失败");
            }
        });

        this.updateBatchById(rankMemberList);
        return ResultUtil.successWithMessage(MessageConf.OPERATION_SUCCESS);
    }

    @Override
    public void deleteRedisByRankMember() {
        // 删除博客相关缓存
        redisUtil.delete(RedisConf.NEW_RANK_MEMBER);
        redisUtil.delete(RedisConf.HOT_RANK_MEMBER);
        redisUtil.delete(RedisConf.RANK_MEMBER_LEVEL + Constants.SYMBOL_COLON + LevelEnum.FIRST);
        redisUtil.delete(RedisConf.RANK_MEMBER_LEVEL + Constants.SYMBOL_COLON + LevelEnum.SECOND);
        redisUtil.delete(RedisConf.RANK_MEMBER_LEVEL + Constants.SYMBOL_COLON + LevelEnum.THIRD);
        redisUtil.delete(RedisConf.RANK_MEMBER_LEVEL + Constants.SYMBOL_COLON + LevelEnum.FOURTH);
    }


    @Override
    public List<RankMemberEntity> setRankAndGradeAndPictureByRankMemberList(List<RankMemberEntity> list) {

        List<String> rankUids = new ArrayList<>();
        List<String> gradeUids = new ArrayList<>();
        Set<String> fileUidSet = new HashSet<>();

        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                fileUidSet.add(item.getFileUid());
            }
            if (StringUtils.isNotEmpty(item.getRankUid())) {
                rankUids.add(item.getRankUid());
            }
            if (StringUtils.isNotEmpty(item.getGradeUid())) {
                gradeUids.add(item.getGradeUid());
            }
        });

        String pictureList = null;
        StringBuffer fileUids = new StringBuffer();
        List<Map<String, Object>> picList = new ArrayList<>();
        // feign分页查询图片数据
        if (fileUidSet.size() > 0) {
            int count = 1;
            for (String fileUid : fileUidSet) {
                fileUids.append(fileUid + ",");
                System.out.println(count % 10);
                if (count % 10 == 0) {
                    pictureList = fileFeignClient.getPicture(fileUids.toString(), ",");
                    List<Map<String, Object>> tempPicList = webUtil.getPictureMap(pictureList);
                    picList.addAll(tempPicList);
                    fileUids = new StringBuffer();
                }
                count++;
            }
            // 判断是否存在图片需要获取
            if (fileUids.length() >= Constants.NUM_32) {
                pictureList = fileFeignClient.getPicture(fileUids.toString(), Constants.SYMBOL_COMMA);
                List<Map<String, Object>> tempPicList = webUtil.getPictureMap(pictureList);
                picList.addAll(tempPicList);
            }
        }

        Collection<RankEntity> rankList = new ArrayList<>();
        Collection<MemberGradeEntity> gradeList = new ArrayList<>();
        if (rankUids.size() > 0) {
            rankList = rankService.listByIds(rankUids);
        }
        if (gradeUids.size() > 0) {
            gradeList = memberGradeService.listByIds(gradeUids);
        }
        Map<String, RankEntity> rankMap = rankList.stream().collect(Collectors.toMap(RankEntity::getUid, v->v, (v1,v2)->v2));
        Map<String, MemberGradeEntity> gradeMap = gradeList.stream().collect(Collectors.toMap(MemberGradeEntity::getUid, v->v, (v1,v2)->v2));
        Map<String, String> pictureMap = picList.stream().collect(Collectors.toMap(
                k-> k.get(SysConf.UID).toString(),
                v-> v.get(SysConf.URL).toString(),
                (v1, v2)->v2));

        for (RankMemberEntity item : list) {
            //设置分类
            if (StringUtils.isNotEmpty(item.getRankUid())) {

                item.setRank(rankMap.get(item.getRankUid()));
                if (rankMap.get(item.getRankUid()) != null) {
                    item.setRankName(rankMap.get(item.getRankUid()).getRankName());
                }
            }

            //获取标签
            if (StringUtils.isNotEmpty(item.getGradeUid())) {

                item.setGrade(gradeMap.get(item.getGradeUid()));
                if (gradeMap.get(item.getGradeUid()) != null) {
                    item.setGradeName(gradeMap.get(item.getGradeUid()).getGradeName());
                }

            }

            //获取图片
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                List<String> pictureUidsTemp = StringUtils.changeStringToString(item.getFileUid(), Constants.SYMBOL_COMMA);
                List<String> pictureListTemp = new ArrayList<String>();

                pictureUidsTemp.forEach(picture -> {
                    pictureListTemp.add(pictureMap.get(picture));
                });
                item.setPhotoList(pictureListTemp);
                // 只设置一张标题图
                if (pictureListTemp.size() > 0) {
                    item.setPhotoUrl(pictureListTemp.get(0));
                } else {
                    item.setPhotoUrl("");
                }
            }
        }
        return list;
    }

    @Override
    public String getArticleByMonth(String monthDate) {
        if (StringUtils.isEmpty(monthDate)) {
            return ResultUtil.errorWithMessage(MessageConf.PARAM_INCORRECT);
        }
        //从Redis中获取内容
        String contentResult = redisUtil.get(SysConf.RANK_CATEGORY_BY_MONTH + SysConf.REDIS_SEGMENTATION + monthDate);

        //判断redis中时候包含该日期下的文章
        if (StringUtils.isNotEmpty(contentResult)) {
            List list = JsonUtils.jsonArrayToArrayList(contentResult);
            return ResultUtil.successWithData(list);
        }

        // 第一次启动的时候归档
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        queryWrapper.eq(BaseSQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(BaseSQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        //因为首页并不需要显示内容，所以需要排除掉内容字段
        queryWrapper.select(RankMemberEntity.class, i -> !i.getProperty().equals(SQLConf.CONTENT));
        List<RankMemberEntity> list = this.list(queryWrapper);

        //给博客增加标签、分类、图片
        list = this.setRankAndGradeAndPictureByRankMemberList(list);

        Map<String, List<RankMemberEntity>> map = new HashMap<>();
        Iterator iterable = list.iterator();
        Set<String> monthSet = new TreeSet<>();
        while (iterable.hasNext()) {
            RankMemberEntity rankMember = (RankMemberEntity) iterable.next();
            Date createTime = rankMember.getCreateTime();

            String month = new SimpleDateFormat("yyyy年MM月").format(createTime).toString();

            monthSet.add(month);

            if (map.get(month) == null) {
                List<RankMemberEntity> rankMemberList = new ArrayList<>();
                rankMemberList.add(rankMember);
                map.put(month, rankMemberList);
            } else {
                List<RankMemberEntity> rankMemberList = map.get(month);
                rankMemberList.add(rankMember);
                map.put(month, rankMemberList);
            }
        }

        // 缓存该月份下的所有文章  key: 月份   value：月份下的所有文章
        map.forEach((key, value) -> {
            redisUtil.set(SysConf.RANK_CATEGORY_BY_MONTH + SysConf.REDIS_SEGMENTATION + key, JsonUtils.objectToJson(value).toString());
        });
        //将从数据库查询的数据缓存到redis中
        redisUtil.set(SysConf.MONTH_SET, JsonUtils.objectToJson(monthSet));
        return ResultUtil.successWithData(map.get(monthDate));
    }

    /**
     * 添加时校验
     *
     * @param count
     * @param level
     * @return
     */
    private String addVerdict(Integer count, Integer level) {

        //添加的时候进行判断
        switch (level) {
            case LevelEnum.FIRST: {
                Long rankMemberFirstCount = Long.valueOf(adminFeignClient.getSysParamsValueByKey(SysConf.RANK_MEMBER_FIRST_COUNT));
                if (count > rankMemberFirstCount) {
                    return ResultUtil.errorWithMessage("一级推荐不能超过" + rankMemberFirstCount + "个");
                }
            }
            break;

            case LevelEnum.SECOND: {
                Long rankMemberSecondCount = Long.valueOf(adminFeignClient.getSysParamsValueByKey(SysConf.RANK_MEMBER_SECOND_COUNT));
                if (count > rankMemberSecondCount) {
                    return ResultUtil.errorWithMessage("二级推荐不能超过" + rankMemberSecondCount + "个");
                }
            }
            break;

            case LevelEnum.THIRD: {
                Long rankMemberThirdCount = Long.valueOf(adminFeignClient.getSysParamsValueByKey(SysConf.RANK_MEMBER_THIRD_COUNT));
                if (count > rankMemberThirdCount) {
                    return ResultUtil.errorWithMessage("三级推荐不能超过" + rankMemberThirdCount + "个");
                }
            }
            break;

            case LevelEnum.FOURTH: {
                Long rankMemberFourthCount = Long.valueOf(adminFeignClient.getSysParamsValueByKey(SysConf.RANK_MEMBER_FOURTH_COUNT));
                if (count > rankMemberFourthCount) {
                    return ResultUtil.errorWithMessage("四级推荐不能超过" + rankMemberFourthCount + "个");
                }
            }
            break;
            default: {

            }
        }
        return null;
    }

    /**
     * 保存成功后，需要发送消息到Es 和 redis
     *
     * @param isSave
     * @param rankMember
     */
    private void updateEsAndRedis(Boolean isSave, RankMemberEntity rankMember) {
        // 保存操作，并且文章已设置发布
        if (isSave && PublishEnum.PUBLISH.equals(rankMember.getIsPublish())) {
            Map<String, Object> map = new HashMap<>();
            map.put(SysConf.COMMAND, SysConf.ADD);
            map.put(SysConf.RANK_MEMBER, rankMember);
            map.put(SysConf.CREATE_TIME, rankMember.getCreateTime());

            //发送到RabbitMq
            rabbitTemplate.convertAndSend(SysConf.EXCHANGE_DIRECT, SysConf.DIDIOK_RANK_MEMBER, map);

        } else if (PublishEnum.NO_PUBLISH.equals(rankMember.getIsPublish())) {

            //这是需要做的是，是删除redis中的该条博客数据
            Map<String, Object> map = new HashMap<>();
            map.put(SysConf.COMMAND, SysConf.EDIT);
            map.put(SysConf.RANK_MEMBER, rankMember);
            map.put(SysConf.CREATE_TIME, rankMember.getCreateTime());
            //发送到RabbitMq
            rabbitTemplate.convertAndSend(SysConf.EXCHANGE_DIRECT, SysConf.DIDIOK_RANK_MEMBER, map);
        }
    }

    /**
     * 设置博客的分类标签和内容
     *
     * @param list
     * @return
     */
    private List<RankMemberEntity> setRankMember(List<RankMemberEntity> list) {
        List<String> fileUidList = new ArrayList<>();
        List<String> rankUids = new ArrayList<>();
        List<String> gradeUids = new ArrayList<>();
        Set<String> userUidList = new HashSet<>();
        Set<String> adminUidList = new HashSet<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                fileUidList.add(item.getFileUid());
            }
            if (StringUtils.isNotEmpty(item.getRankUid())) {
                rankUids.add(item.getRankUid());
            }
            if (StringUtils.isNotEmpty(item.getGradeUid())) {
                gradeUids.add(item.getGradeUid());
            }

            // 判断用户投稿，还是后台管理员添加
            if (ContributeSourceEnum.USER_PUBLISH.equals(item.getRankMemberSource())) {
                if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                    userUidList.add(item.getCreateUserUid());
                }
            } else {
                if (StringUtils.isNotEmpty(item.getAdminUid())) {
                    adminUidList.add(item.getAdminUid());
                }
            }
        });
        Collection<RankEntity> rankList = new ArrayList<>();
        Collection<MemberGradeEntity> gradeList = new ArrayList<>();
        if (rankUids.size() > 0) {
            rankList = rankService.listByIds(rankUids);
        }
        if (gradeUids.size() > 0) {
            gradeList = memberGradeService.listByIds(gradeUids);
        }

        Map<String, RankEntity> rankMap = new HashMap<>();
        Map<String, MemberGradeEntity> gradeMap = new HashMap<>();
        Map<String, String> pictureMap = fileFeignUtil.fileUidToFileUrlMap(fileUidList);

        rankList.forEach(item -> {
            rankMap.put(item.getUid(), item);
        });

        gradeList.forEach(item -> {
            gradeMap.put(item.getUid(), item);
        });


        return list;
    }

    /**
     * 设置博客的分类标签和内容
     *
     * @param
     * @return
     */
    private RankMemberEntity setRankMemberWithGradeAndRank(RankMemberEntity rankMember) {
        String rankUid = rankMember.getRankUid();
        String gradeUid = rankMember.getGradeUid();

        if (StringUtils.isNotEmpty(rankUid)) {
            RankEntity rankEntity = rankService.getById(rankUid);
            rankMember.setRank(rankEntity);
        }
        if (StringUtils.isNotEmpty(gradeUid)) {
            MemberGradeEntity memberGradeEntity = memberGradeService.getById(gradeUid);
            rankMember.setGrade(memberGradeEntity);
        }

        return rankMember;
    }

    /**
     * 修改榜单成员content
     *
     * @param generalEditDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateRankMemberContent(GeneralEditDto generalEditDto) {
        LambdaQueryWrapper<RankMemberEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RankMemberEntity::getUid, generalEditDto.getBizUid());
        RankMemberEntity blog = this.getOne(wrapper);
        if (blog == null) {
            throw new QueryException("未查询到榜单成员");
        }
        return rankMemberDao.updateContentById(generalEditDto.getBizUid(), generalEditDto.getContent());
    }

    /**
     * 根据 fileUid 更新对应的所有榜单成员，将其中的fileUid全都更换
     *
     * @param fileUid
     * @return
     */
    @Override
    public boolean updateRankMemberPictureByPictureUid(String fileUid) {
        // 这里需要更新所有榜单成员，将图片替换成 裁剪的图片
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(SQLConf.FILE_UID, fileUid);
        List<RankMemberEntity> list = this.list(queryWrapper);
        if (list.size() > 0) {
            list.forEach(item -> {
                item.setFileUid(fileUid);
            });
            this.updateBatchById(list);

            Map<String, Object> map = new HashMap<>();
            map.put(SysConf.COMMAND, SysConf.EDIT_BATCH);

            //发送到RabbitMq
            rabbitTemplate.convertAndSend(SysConf.EXCHANGE_DIRECT, SysConf.DIDIOK_RANK_MEMBER, map);
        }
        return true;
    }

    private static void checkOrSetAuth(RankMemberEntity rankMember, boolean checkSuccess) {
        if (checkSuccess) {
            rankMember.setVisitAuthSuccess(true);
        } else {
            rankMember.setVisitAuthSuccess(false);
        }
    }

    /**
     * 根据Oid列表查询榜单成员
     *
     * @param memberOids
     * @return
     */
    @Override
    public List<RankMemberEntity> listByOids(List<String> memberOids) {
        QueryWrapper<RankMemberEntity> blogQueryWrapper = new QueryWrapper<>();
        blogQueryWrapper.in(SQLConf.OID, memberOids);
        return this.list(blogQueryWrapper);
    }

    /**
     * 根据各种业务id列表查询对应的对象集合
     *
     * @param businessIdListDto
     * @return
     */
    @Override
    public BusinessObjectListDto listBusinessObjectByIds(BusinessIdListDto businessIdListDto) {
        BusinessObjectListDto businessObjectListDto = new BusinessObjectListDto();

        List<String> rankMemberUids = businessIdListDto.getRankMemberUids();
        List<String> rankMemberOids = businessIdListDto.getRankMemberOids();
        List<String> rankUids = businessIdListDto.getRankUids();
        List<String> gradeUids = businessIdListDto.getGradeUids();
        List<String> catUids = businessIdListDto.getCatUids();
        
        if (rankMemberUids.size() > 0) {
            List<RankMemberEntity> rankMemberList = this.listByIds(rankMemberUids);
            List<RankMemberDto> rankMemberDtoList = rankMemberList.stream().map(item->{
                RankMemberDto rankMemberDto = new RankMemberDto();
                BeanUtils.copyProperties(item, rankMemberDto);
                return rankMemberDto;
            }).collect(Collectors.toList());
            businessObjectListDto.setRankMemberList(rankMemberDtoList);
        }

        if (rankMemberOids.size() > 0) {
            List<RankMemberEntity> rankMemberList = this.listByOids(rankMemberOids);
            List<RankMemberDto> rankMemberDtoList = rankMemberList.stream().map(item->{
                RankMemberDto rankMemberDto = new RankMemberDto();
                BeanUtils.copyProperties(item, rankMemberDto);
                return rankMemberDto;
            }).collect(Collectors.toList());
            businessObjectListDto.setRankMemberListByOid(rankMemberDtoList);
        }

        if (rankUids.size() > 0) {
            List<RankEntity> rankList = rankService.listByIds(rankUids);
            List<RankDto> rankDtoList = rankList.stream().map(item->{
                RankDto rankDto = new RankDto();
                BeanUtils.copyProperties(item, rankDto);
                return rankDto;
            }).collect(Collectors.toList());
            businessObjectListDto.setRankList(rankDtoList);
        }

        if (gradeUids.size() > 0) {
            List<MemberGradeEntity> gradeList = memberGradeService.listByIds(gradeUids);
            List<MemberGradeDto> memberGradeDtoList = gradeList.stream().map(item->{
                MemberGradeDto memberGradeDto = new MemberGradeDto();
                BeanUtils.copyProperties(item, memberGradeDto);
                return memberGradeDto;
            }).collect(Collectors.toList());
            businessObjectListDto.setGradeList(memberGradeDtoList);
        }

        if (catUids.size() > 0) {
            List<RankCategoryEntity> catList = rankCategoryService.listByIds(catUids);
            List<RankCategoryDto> rankCategoryDtoList = catList.stream().map(item->{
                RankCategoryDto rankCategoryDto = new RankCategoryDto();
                BeanUtils.copyProperties(item, rankCategoryDto);
                return rankCategoryDto;
            }).collect(Collectors.toList());
            businessObjectListDto.setCatList(rankCategoryDtoList);
        }

        return businessObjectListDto;
    }

    /**
     * 根据用户列表ID  查询各用户发表博客数
     *
     * @return
     */
    @Override
    public List<Map<String, String>> getUsersRankMemberCountByUserIds(List<String> userUids) {
        return rankMemberDao.getUsersRankMemberCountByUserId(userUids);
    }

    /**
     * 根据用户id和来源统计榜单成员的数量
     *
     * @param userUid
     * @param source
     * @return
     */
    @Override
    public Integer countRankMemberByUserUidAndSource(String userUid, String source) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.CREATE_USER_UID, userUid);
        queryWrapper.eq(SQLConf.ARTICLE_SOURCE, ContributeSourceEnum.USER_PUBLISH);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(SQLConf.AUDIT_STATUS, AuditStatusEnum.AGREE);
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        Integer publishCount = this.count(queryWrapper);
        redisUtil.setEx(RedisConf.RANK_MEMBER_PUBLISH_COUNT + Constants.SYMBOL_COLON + userUid, JsonUtils.objectToJson(publishCount), 10, TimeUnit.MINUTES);

        return publishCount;
    }

    /**
     * 根据用户id和文章来源，查询文章的oid和Uid
     *
     * @param userUid
     * @param source
     * @return
     */
    @Override
    public List<RankMemberEntity> listIdByUserUidAndSource(String userUid, String source) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.CREATE_USER_UID, userUid);
        queryWrapper.eq(SQLConf.RANK_MEMBER_SOURCE, ContributeSourceEnum.USER_PUBLISH);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        // 只获取uid信息
        queryWrapper.select(SQLConf.OID, SQLConf.UID);
        return this.list(queryWrapper);
    }

    /**
     * 获取博客列表
     * @param rankMemberDto
     * @return
     */
    public IPage<RankMemberEntity> getRankMemberPageList(RankMemberDto rankMemberDto) {
//        IPage<RankMemberEntity> pageList = getPageListWithGradeAndRankAndTag(rankMemberDto);

        //分页
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(rankMemberDto.getCurrentPage());
        page.setSize(rankMemberDto.getPageSize());

        if (ActivityOrderByEnum.FORWARD.getCode().equals(rankMemberDto.getActivityOrderBy())) {
            // 按照活动开始时间降序
            rankMemberDto.setAttrOrderBy(SQLConf.START_TIME + " desc");
        } else if (ActivityOrderByEnum.LATEST_RELEASE.getCode().equals(rankMemberDto.getActivityOrderBy())) {
            // 按照创建时间降序
            rankMemberDto.setOrderBy(SQLConf.CREATE_TIME + " desc");
        } else if (ActivityOrderByEnum.HISTORY.getCode().equals(rankMemberDto.getActivityOrderBy())) {
            // 按照活动开始时间降序
            rankMemberDto.setAttrOrderBy(SQLConf.START_TIME + " desc");
        } else {
            // 按照活动开始时间升序
            rankMemberDto.setAttrOrderBy(SQLConf.START_TIME + " asc");
        }
//        rankMemberDto.setAuditStatus(AuditStatusEnum.AGREE);
//        rankMemberDto.setIsPublish(PublishEnum.PUBLISH);
        rankMemberDto.setStatus(StatusEnum.ENABLE);

        Page<RankMemberEntity> pageList = rankMemberDao.queryPageWithAttrInfo(page, rankMemberDto);
        List<RankMemberEntity> list = pageList.getRecords();

        if (list.size() == 0) {
            return pageList;
        }

        Date nowDate = new Date();
        list.forEach(item -> {

            // 是否活动结束
            if(null != item.getEndTime()){
                item.setIsEnd(nowDate.after(item.getEndTime()) ? 1 : 0);
            }

            // 是否报名截止
            if(null != item.getApplyEndTime()) {
                item.setIsApplyEnd(nowDate.after(item.getApplyEndTime()) ? 1 : 0);
            }

        });

        if(null == pageList){
            return null;
        }

        final StringBuffer fileUids = new StringBuffer();

        List<String> rankMemberUids = new ArrayList<>();
        List<String> userUids = new ArrayList<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                fileUids.append(item.getFileUid() + SysConf.FILE_SEGMENTATION);
            }

            userUids.add(item.getCreateUserUid());
            rankMemberUids.add(item.getUid());
        });
        R userMapResult= userFeignClient.listUserNameAndAvatarByUids(userUids);
        Map<String, UserDto> userMap = null;
        if (userMapResult.getCode() == 0) {
            userMap = userMapResult.getData(new TypeReference<Map<String, UserDto>>(){});
        }else {
            throw new FeignException("feign调用异常（获取带头像的用户Map）：失败");
        }

        for (Map.Entry<String, UserDto> entry : userMap.entrySet()) {
            UserDto userDto = entry.getValue();
            if (null != userDto && StringUtils.isNotEmpty(userDto.getAvatar())) {
                fileUids.append(userDto.getAvatar() + SysConf.FILE_SEGMENTATION);
            }
        }
        String pictureList = null;
        if (fileUids != null) {
            pictureList = fileFeignClient.getPicture(fileUids.toString(), SysConf.FILE_SEGMENTATION);
        }

        List<Map<String, Object>> picList = webUtil.getPictureMap(pictureList);

        Map<String, String> pictureMap = new HashMap<>();


        picList.forEach(item -> {
            pictureMap.put(item.get(SQLConf.UID).toString(), item.get(SQLConf.URL).toString());
        });

        for (RankMemberEntity item : list) {

            //获取图片
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                List<String> pictureUidsTemp = StringUtils.changeStringToString(item.getFileUid(), SysConf.FILE_SEGMENTATION);
                List<String> pictureListTemp = new ArrayList<>();

                pictureUidsTemp.forEach(picture -> {
                    pictureListTemp.add(pictureMap.get(picture));
                });
                // 只设置一张标题图
                if (pictureListTemp.size() > 0) {
                    item.setPhotoUrl(pictureListTemp.get(0));
                } else {
                    item.setPhotoUrl("");
                }
            }
            UserDto userDto = userMap.get(item.getCreateUserUid());
            if (null == userDto) {
                continue;
            }
            String avatarFileUid = userDto.getAvatar();
            // 设置头像
            if (StringUtils.isNotEmpty(avatarFileUid)) {
                userDto.setPhotoUrl(pictureMap.get(avatarFileUid));
            }
            item.setUser(userDto);
        }
//        pageList.setRecords(list);
        return pageList;
    }

    @Override
    public IPage<RankMemberEntity> getPageList(RankMemberDto rankMemberDto) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(rankMemberDto.getKeyword())) {
            queryWrapper.like(SQLConf.MEMBER_NAME, rankMemberDto.getKeyword());
        }
        if (StringUtils.isNotEmpty(rankMemberDto.getMemberName())) {
            queryWrapper.like(SQLConf.MEMBER_NAME, rankMemberDto.getMemberName());
        }
        if (StringUtils.isNotEmpty(rankMemberDto.getCatUid())) {
            queryWrapper.eq("cat_uid", rankMemberDto.getCatUid());
        }

        if (rankMemberDto.getStatus() != null) {
            queryWrapper.eq(SQLConf.STATUS, rankMemberDto.getStatus());
        }

        if (StringUtils.isNotEmpty(rankMemberDto.getOrderByAscColumn())) {
            // 将驼峰转换成下划线
            String column = StringUtils.underLine(new StringBuffer(rankMemberDto.getOrderByAscColumn())).toString();
            queryWrapper.orderByAsc(column);
        } else if (StringUtils.isNotEmpty(rankMemberDto.getOrderByDescColumn())) {
            // 将驼峰转换成下划线
            String column = StringUtils.underLine(new StringBuffer(rankMemberDto.getOrderByDescColumn())).toString();
            queryWrapper.orderByDesc(column);
        } else {
            queryWrapper.orderByDesc(SQLConf.SORT);
            queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        }

        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(rankMemberDto.getCurrentPage());
        page.setSize(rankMemberDto.getPageSize());
        IPage<RankMemberEntity> pageList = this.page(page, queryWrapper);
        List<RankMemberEntity> rankMemberList = pageList.getRecords();

        List<String> createUserUids = new ArrayList<>();
        rankMemberList.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                createUserUids.add(item.getCreateUserUid());
            }
        });
        List<UserDto> createUserList = new ArrayList<>();
        R userResult = userFeignClient.listUserByUids(createUserUids);
        if (userResult.getCode() == 0) {
            createUserList = userResult.getData(new TypeReference<List<UserDto>>(){});
        }else {
            throw new FeignException("feign调用异常（根据用户id列表找用户）：失败");
        }
        Map<String, UserDto> map = new HashMap<>();
        createUserList.forEach(item -> {
            item.setPassword("");
            map.put(item.getUid(), item);
        });
        pageList.setRecords(rankMemberList);
        return pageList;
    }

    @Override
    public RankMemberEntity downloadRankMember(String memberUid) {
        RankMemberEntity blog = this.getById(memberUid);
        if (blog == null || StatusEnum.ENABLE != blog.getStatus()) {
            throw new QueryException("博客不存在");
        }
        String userUid = RequestHolder.getUserUid();
        if (StringUtils.isNotEmpty(blog.getCreateUserUid()) && !blog.getCreateUserUid().equals(userUid)) {
            throw new QueryException("无法下载其它用户的文章");
        }
        // 将html转换成markdown
        String blogContent = FileUtils.htmlToMarkdown(blog.getContent());
        blog.setContent(blogContent);
        return blog;
    }

    @Override
    public IPage<RankMemberEntity> getSameRankMemberByTagUid(String tagUid) {
        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        Page<RankMemberEntity> page = new Page<>();
        page.setCurrent(1);
        page.setSize(10);
        queryWrapper.like(SQLConf.TAG_UID, tagUid);
        queryWrapper.orderByDesc(SQLConf.CREATE_TIME);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        IPage<RankMemberEntity> pageList = this.page(page, queryWrapper);
        List<RankMemberEntity> list = pageList.getRecords();
        list = this.setTagAndRankByRankMemberList(list);
        pageList.setRecords(list);
        return pageList;
    }

    /**
     * 设置博客的分类标签和内容
     *
     * @param list
     * @return
     */
    private List<RankMemberEntity> setRankMemberInfoWithGradePicRankBatch(List<RankMemberEntity> list) {
        List<String> fileUidList = new ArrayList<>();
        List<String> rankUids = new ArrayList<>();
        List<String> gradeUids = new ArrayList<>();
        Set<String> userUidList = new HashSet<>();
        Set<String> adminUidList = new HashSet<>();
        list.forEach(item -> {
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                fileUidList.add(item.getFileUid());
            }
            if (StringUtils.isNotEmpty(item.getRankUid())) {
                rankUids.add(item.getRankUid());
            }
            if (StringUtils.isNotEmpty(item.getGradeUid())) {
                gradeUids.add(item.getGradeUid());
            }

            // 判断用户投稿，还是后台管理员添加
            if (ContributeSourceEnum.USER_PUBLISH.equals(item.getRankMemberSource())) {
                if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                    userUidList.add(item.getCreateUserUid());
                }
            } else {
                if (StringUtils.isNotEmpty(item.getAdminUid())) {
                    adminUidList.add(item.getAdminUid());
                }
            }
        });
        Collection<RankEntity> rankList = new ArrayList<>();
        Collection<MemberGradeEntity> gradeList = new ArrayList<>();
        if (rankUids.size() > 0) {
            rankList = rankService.listByIds(rankUids);
        }
        if (gradeUids.size() > 0) {
            gradeList = memberGradeService.listByIds(gradeUids);
        }

        Map<String, RankEntity> rankMap = new HashMap<>();
        Map<String, MemberGradeEntity> gradeMap = new HashMap<>();
        Map<String, String> pictureMap = fileFeignUtil.fileUidToFileUrlMap(fileUidList);

        rankList.forEach(item -> {
            rankMap.put(item.getUid(), item);
        });

        gradeList.forEach(item -> {
            gradeMap.put(item.getUid(), item);
        });


        // 获取用户信息
        List<UserDto> userList = new ArrayList<>();
        if (userUidList.size() > 0) {
            R result = userFeignClient.getUserListAndAvatarByIds(userUidList);
            if (result.getCode() == 0) {
                userList = result.getData(new TypeReference<List<UserDto>>(){});
            }else {
                throw new FeignException("feign调用异常（通过ids获取用户列表【携带用户头像和背景图片】）：失败");
            }
        }
        List<AdminDto> adminList = new ArrayList<>();
        if (adminUidList.size() > 0) {
            R result = adminFeignClient.getAdminListByUids(adminUidList);
            if (result.getCode() == 0) {
                adminList = result.getData(new TypeReference<List<AdminDto>>(){});
            }else {
                throw new FeignException("feign调用异常（通过 ids 获取管理员列表）：失败");
            }
        }
        Map<String, UserDto> userMap = new HashMap<>();
        Map<String, AdminDto> adminMap = new HashMap<>();
        userList.forEach(item -> {
            userMap.put(item.getUid(), item);
        });
        adminList.forEach(item -> {
            adminMap.put(item.getUid(), item);
        });

        for (RankMemberEntity item : list) {

            //设置分类
            if (StringUtils.isNotEmpty(item.getRankUid())) {
                item.setRank(rankMap.get(item.getRankUid()));
            }

            //获取标签
            if (StringUtils.isNotEmpty(item.getGradeUid())) {
                item.setGrade(gradeMap.get(item.getGradeUid()));
            }

            //获取图片
            if (StringUtils.isNotEmpty(item.getFileUid())) {
                List<String> pictureUidsTemp = StringUtils.changeStringToString(item.getFileUid(), SysConf.FILE_SEGMENTATION);
                List<String> pictureListTemp = new ArrayList<>();

                pictureUidsTemp.forEach(picture -> {
                    pictureListTemp.add(pictureMap.get(picture));
                });
                item.setPhotoList(pictureListTemp);
            }

            //获取用户【判断是用户投稿，还是后台添加】
            if (ContributeSourceEnum.USER_PUBLISH.equals(item.getRankMemberSource())) {
                if (StringUtils.isNotEmpty(item.getCreateUserUid())) {
                    item.setUser(userMap.get(item.getCreateUserUid()));
                }
            } else {
                if (StringUtils.isNotEmpty(item.getAdminUid())) {
                    UserDto user = new UserDto();
                    AdminDto admin = adminMap.get(item.getAdminUid());
                    if (admin != null) {
                        user.setAvatar(admin.getAvatar());
                        user.setUid(admin.getUid());
                        user.setOccupation(admin.getOccupation());
                        user.setGender(admin.getGender());
                        user.setSummary(admin.getSummary());
                        user.setNickname(admin.getNickname());
                        user.setPhotoUrl(admin.getPhotoUrl());
                        item.setUser(user);
                    }
                }
            }
        }
        return list;
    }

    /**
     * List<userIds> 转换为 Map<userId , UserDto>
     *
     * @param userIds
     * @return
     */
    private Map<String, UserDto> usersConvert(List<String> userIds) {
        Map<String, UserDto> userMap = new HashMap<>();
        if (userIds.size() > 0) {
            R userResult = userFeignClient.listUserByUids(userIds);
            List<UserDto> userDtoList;
            if (userResult.getCode() == 0) {
                userDtoList = userResult.getData(new TypeReference<List<UserDto>>(){});
            }else {
                throw new FeignException("feign调用异常（根据用户id列表找用户）：失败");
            }

            // 设置头像
            userUtil.setUserAvatar(userDtoList);
            // 过滤敏感信息
            List<UserDto> userList = userUtil.convertUserList(userDtoList);
            for (UserDto user : userList) {
                userMap.put(user.getUid(), user);
            }
        }
        return userMap;
    }

    @Override
    public Integer getContinuousPublishRankMemberCount(String userUid) {
        // 获取连续发表文章数
        ContinuousDayDto continuousDayVO = rankMemberDao.getPublishContinuousDays(userUid, DateUtils.getToday());
        return continuousDayVO == null ? 0 : continuousDayVO.getContinuousDays();
    }

    @Override
    public Integer getRankMemberClickCount(String userUid) {

        QueryWrapper<RankMemberEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.CREATE_USER_UID, userUid);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.eq(SQLConf.IS_PUBLISH, PublishEnum.PUBLISH);
        queryWrapper.select("sum(click_count) as sum");
        Map<String, Object> map = this.getMap(queryWrapper);
        if (map.get("sum") != null) {
            return Integer.valueOf(map.get("sum").toString());
        }
        return 0;
    }

    /**
     * 根据 uid/oid 查询 RankMemberEntity(活动列表页使用)
     *
     * @param uid
     * @param oid
     * @return
     */
    @Override
    public RankMemberEntity getWithAttrInfoById(String uid, Integer oid) {
        RankMemberEntity rankMemberEntity = rankMemberDao.getWithAttrInfoById(uid, oid);
        String startTimeStr = DateUtils.dateTimeToStr(rankMemberEntity.getStartTime());
        String endTimeStr = DateUtils.dateTimeToStr(rankMemberEntity.getEndTime());
        rankMemberEntity.setTimeRange(startTimeStr + " ~ " + endTimeStr);
        String province = rankMemberEntity.getProvince();
        String city = rankMemberEntity.getCity();
        String address = rankMemberEntity.getAddress();
        rankMemberEntity.setFullAddress(province + city + address);

        Date nowDate = new Date();
        // 是否活动结束
        if(null != rankMemberEntity.getEndTime()){
            rankMemberEntity.setIsEnd(nowDate.after(rankMemberEntity.getEndTime()) ? 1 : 0);
        }

        // 是否报名截止
        if(null != rankMemberEntity.getApplyEndTime()) {
            rankMemberEntity.setIsApplyEnd(nowDate.after(rankMemberEntity.getApplyEndTime()) ? 1 : 0);
        }
        return rankMemberEntity;
    }

    /**
     * 根据 uid/oid 查询 RankMemberEntity(活动详情页使用)
     *
     * @param uid
     * @param oid
     * @return
     */
    @Override
    public RankMemberEntity getRankMemberDetailInfoById(String uid, Integer oid) {
        RankMemberEntity rankMemberEntity = rankMemberDao.getRankMemberDetailInfoById(uid, oid);
        String startTimeStr = DateUtils.dateTimeToStr(rankMemberEntity.getStartTime());
        String endTimeStr = DateUtils.dateTimeToStr(rankMemberEntity.getEndTime());
        rankMemberEntity.setTimeRange(startTimeStr + " ~ " + endTimeStr);
        String province = rankMemberEntity.getProvince();
        String city = rankMemberEntity.getCity();
        String address = rankMemberEntity.getAddress();
        rankMemberEntity.setFullAddress(province + city + address);

        Date nowDate = new Date();
        // 是否活动结束
        if(null != rankMemberEntity.getEndTime()){
            rankMemberEntity.setIsEnd(nowDate.after(rankMemberEntity.getEndTime()) ? 1 : 0);
        }

        // 是否报名截止
        if(null != rankMemberEntity.getApplyEndTime()) {
            rankMemberEntity.setIsApplyEnd(nowDate.after(rankMemberEntity.getApplyEndTime()) ? 1 : 0);
        }
        // 是否领队报名截止
        if(null != rankMemberEntity.getLeaderApplyEndTime()) {
            rankMemberEntity.setIsLeaderApplyEnd(nowDate.after(rankMemberEntity.getLeaderApplyEndTime()) ? 1 : 0);
        }
        return rankMemberEntity;
    }

    /**
     * 根据 条件 查询 RankMemberUid
     *
     * @param rankMemberDto
     * @return
     */
    @Override
    public List<RankMemberDto> listRankMemberUid(RankMemberDto rankMemberDto) {

        return rankMemberDao.listRankMemberUid(rankMemberDto);
    }

    public enum AdminOption {
        /**
         * 修改
         */
        EDIT(),
        /**
         * 删除
         */
        DELETE(),
        /**
         * 审核/拒审
         */
        AUDIT(),
        /**
         * 发布/下架
         */
        PUBLISH();
    }

}